// ======
//                ORBITER MODULE: DeltaGlider
//                   
//          
//                  
//
// DeltaGlider.cpp
// Reference implementation of delta glider vessel class module
// ======
 
#define ORBITER_MODULE
#pragma warning(disable : 4996)// this is for visual studio pro


#include "DeltaGlider.h"
#include "ScnEditorAPI.h"
#include "DlgCtrl.h"
#include "at1000.msh.resource.h"
#include <stdio.h>
#include <math.h>
#include "OrbiterSoundSDK35.h"

#define LOADBMP(id) (LoadBitmap (g_Param.hDLL, MAKEINTRESOURCE (id)))

// ======
// Global parameters
// ======
GDIParams g_Param;

static HELPCONTEXT g_hc = {
	"html/vessels/DeltaGlider.chm",
	0,
	"html/vessels/DeltaGlider.chm::/DeltaGlider.hhc",
	"html/vessels/DeltaGlider.chm::/DeltaGlider.hhk"
};
// ======
// Local prototypes

BOOL CALLBACK Ctrl_DlgProc (HWND, UINT, WPARAM, LPARAM);
void UpdateCtrlDialog (DeltaGlider *dg, HWND hWnd = 0);

//BOOL CALLBACK Damage_DlgProc (HWND, UINT, WPARAM, LPARAM);
//void UpdateDamageDialog (DeltaGlider *dg, HWND hWnd = 0);

// ======
// Airfoil coefficient functions
// Return lift, moment and zero-lift drag coefficients as a
// function of angle of attack (alpha or beta)
// ======

// 1. vertical lift component (wings and body)

void VLiftCoeff (VESSEL *v, double aoa, double M, double Re, void *context, double *cl, double *cm, double *cd)
{
	int i;
	const int nabsc = 9;
	static const double AOA[nabsc] = {-180*RAD,-60*RAD,-30*RAD, -2*RAD, 15*RAD,20*RAD,25*RAD,60*RAD,180*RAD};
	static const double CL[nabsc]  = {       0,      0,   -0.4,      0,    0.7,     1,   0.8,     0,      0};
	static const double CM[nabsc]  = {       0,      0,  0.014, 0.0039, -0.006,-0.008,-0.010,     0,      0};
	for (i = 0; i < nabsc-1 && AOA[i+1] < aoa; i++);
	double f = (aoa-AOA[i]) / (AOA[i+1]-AOA[i]);
	*cl = CL[i] + (CL[i+1]-CL[i]) * f;  // aoa-dependent lift coefficient
	*cm = CM[i] + (CM[i+1]-CM[i]) * f;  // aoa-dependent moment coefficient
	double saoa = sin(aoa);
	double pd = 0.015 + 0.4*saoa*saoa;  // profile drag
	*cd = pd + oapiGetInducedDrag (*cl, 1.5, 0.7) + oapiGetWaveDrag (M, 0.75, 1.0, 1.1, 0.04);
	// profile drag + (lift-)induced drag + transonic/supersonic wave (compressibility) drag
}

// 2. horizontal lift component (vertical stabilisers and body)

void HLiftCoeff (VESSEL *v, double beta, double M, double Re, void *context, double *cl, double *cm, double *cd)
{
	int i;
	const int nabsc = 8;
	static const double BETA[nabsc] = {-180*RAD,-135*RAD,-90*RAD,-45*RAD,45*RAD,90*RAD,135*RAD,180*RAD};
	static const double CL[nabsc]   = {       0,    +0.3,      0,   -0.3,  +0.3,     0,   -0.3,      0};
	for (i = 0; i < nabsc-1 && BETA[i+1] < beta; i++);
	*cl = CL[i] + (CL[i+1]-CL[i]) * (beta-BETA[i]) / (BETA[i+1]-BETA[i]);
	*cm = 0.0;
	*cd = 0.015 + oapiGetInducedDrag (*cl, 1.5, 0.6) + oapiGetWaveDrag (M, 0.75, 1.0, 1.1, 0.04);
}

// ======
// Specialised vessel class DeltaGlider
// ======

// --------------------------------------------------------------
// Constructor
// --------------------------------------------------------------
DeltaGlider::DeltaGlider (OBJHANDLE hObj, int fmodel)
: VESSEL2 (hObj, fmodel)
{
	int i, j;
    
	

	
	
	modelidx = (fmodel ? 1 : 0);
	aoa_ind = PI;
	slip_ind = PI*0.5;
	load_ind = PI;
	
    TEST_STATUS       = DOOR_CLOSED;

	//new systems
	charging_status   = DOOR_CLOSED;     // solar panel testing   closed = no charge  open = charging
	engine_status     = DOOR_CLOSED;


   //Environmental Life Support System
   
     
	battery_charge_001          =100;
	battery_charge_002          =0;
	battery_charge_003          =0;
	battery_charge_004          =0;
	
	
	CabinThermostat_battery_loop                =1;
	lastSimTime                 = 0;
	CabinTemp                   = 105.3;
    Update_Temp                 = 0;
    CabinThermostat             = 0;
	CabinThermostatSet          = 70;    
	CabinTemperatureSet         = 72;
	RadiatorThermostat1         = 0;
	RadiatorThermostat2         = 0;
	RadiatorThermostat3         = 0;
	RadiatorThermostat4         = 0;
	ShipAge_seconds             = 0;
    ShipAge_Min                 = 0;
	ShipAge_hours               = 0;
	FAN_AIR_LOOP_001            = SYSTEM_OFF;
	FAN_AIR_LOOP_002            = SYSTEM_OFF;
	FAN_AIR_LOOP_003            = SYSTEM_OFF;
	carbon_dioxide_level_001    = 0.03;
    carbon_dioxide_level_002    = 0.03;
    carbon_dioxide_code         = 1;
	RadiatorTemp1               = 100;
    RadiatorTemp2               = 100;
	RadiatorTemp3               = 100;
    RadiatorTemp4               = 100;
	Radiator_loop               = 1;
	totalcrew                   = 0;
    Environmental_Control_Computer_page = 0;
    Environmental_Control_Computer_page_Count = 3;
    
    


	//charging_system   = SYSTEM_OFF;   // this is not working
	
	charging_proc     = 0.0;            // not sure here so I added both 
	gear_status       = DOOR_CLOSED;
	gear_proc         = 0.0;
	rcover_status     = DOOR_CLOSED;
	rcover_proc       = 0.0;
	NOSE_CONE_STATUS  = DOOR_CLOSED;
	nose_cone_proc    = 0.0;
	ladder_status     = DOOR_CLOSED;
	ladder_proc       = 0.0;
	hatch_status      = DOOR_CLOSED;
	hatch_proc        = 0.0;
	brake_status      = DOOR_CLOSED;
	brake_proc        = 0.0;
	radiator_status   = DOOR_CLOSED;
	radiator_proc     = 0.0;
	visual            = NULL;
	exmesh            = NULL;
	//BAY_DOORS         = SYSTEM_ON;
	hatch_vent        = NULL;
	insignia_tex      = NULL;
	campos            = CAM_GENERIC;
    
    OUTER_AIRLOCK_DOOR_STATUS      = DOOR_CLOSED;
	INNER_AIRLOCK_DOOR_STATUS      = DOOR_CLOSED;
	AIRLOCK_TUBE_STATUS            = DOOR_CLOSED;
	CHAMBER_STATUS                 = DOOR_CLOSED;
	outer_air_lock_proc        = 0.0;
	inner_air_lock_proc        = 0.0;
    air_lock_tube_proc         = 0.0;





	CHECK_HUD_PANEL_STATE = 0;
	
	//Crew.SetAirlockDoorState(FALSE) ;  we need to look at this I do not understand how touse this
	SelectedUmmuMember = 0;
    SelectedCrgo       = 0;
	cargoUpDown        = 2;
	POWER = SYSTEM_OFF;
    TURBINE_FUEL_LEFT_POWER          = SYSTEM_OFF;
	TURBINE_IGNITION_LEFT_POWER      = SYSTEM_OFF;
	TURBINE_START_LEFT_POWER         = SYSTEM_OFF;
	TURBINE_RUNNING_LEFT             = SYSTEM_OFF;
	TURBINE_RUNNING_RIGHT            = SYSTEM_OFF;
	TURBINE_FUEL_RIGHT_POWER         = SYSTEM_OFF;
	TURBINE_IGNITION_RIGHT_POWER     = SYSTEM_OFF;
	TURBINE_START_RIGHT_POWER        = SYSTEM_OFF;
    TURBINE_STARTING_LEFT            = SYSTEM_OFF;            
	TURBINE_STARTING_RIGHT           = SYSTEM_OFF;
	TURBINE_REVERSER                 = SYSTEM_OFF;          
    REVERSER_STSTUS                  = DOOR_CLOSED;
    reverser_proc                    = 0.0;

// cargo bay    
    BAY_DOOR_FORWARD_RIGHT_STATUS = DOOR_CLOSED;
    BAY_DOOR_FORWARD_LEFT_STATUS = DOOR_CLOSED;
	BAY_DOOR_AFT_RIGHT_STATUS = DOOR_CLOSED;
    BAY_DOOR_AFT_LEFT_STATUS = DOOR_CLOSED;
	bay_door_forward_right_proc   = 0.0;
    bay_door_forward_left_proc   = 0.0;
	bay_door_aft_right_proc   = 0.0;
    bay_door_aft_left_proc   = 0.0;
    MASTER_BAY_DOORS_POWER           = SYSTEM_OFF;        
	BAY_DOOR_FORWARD_RIGHT_POWER     = SYSTEM_OFF;  
	BAY_DOOR_AFT_RIGHT_POWER         = SYSTEM_OFF;   
	BAY_DOOR_FORWARD_LEFT_POWER      = SYSTEM_OFF;
	BAY_DOOR_AFT_LEFT_POWER          = SYSTEM_OFF;
    AIRLOCK_MASTER_POWER             = SYSTEM_OFF;
	AIRLOCK_TUBE_POWER               = SYSTEM_OFF;
	INNER_AIR_LOCK_DOOR_POWER        = SYSTEM_OFF;
	OUTER_AIR_LOCK_DOOR_POWER        = SYSTEM_OFF;
	NOSE_CONE_POWER                  = SYSTEM_OFF;
	CHAMBER_POWER                    = SYSTEM_OFF;
	DOCK_RELEASE_POWER               = SYSTEM_OFF;
	
	CARGO_MAX_DIST                   = 20000;



	//scram system left
	SCRAM_FUEL_LEFT_POWER            = SYSTEM_OFF;
	SCRAM_IGNITION_LEFT_POWER        = SYSTEM_OFF;
	SCRAM_START_LEFT_POWER           = SYSTEM_OFF;
    //scram system right
    SCRAM_FUEL_RIGHT_POWER            = SYSTEM_OFF;
	SCRAM_IGNITION_RIGHT_POWER        = SYSTEM_OFF;
	SCRAM_START_RIGHT_POWER           = SYSTEM_OFF;
    //rocket system left
	ROCKET_FUEL_LEFT_POWER            = SYSTEM_OFF;
	ROCKET_IGNITION_LEFT_POWER        = SYSTEM_OFF;
    //rocket system right
	ROCKET_FUEL_RIGHT_POWER           = SYSTEM_OFF;
	ROCKET_IGNITION_RIGHT_POWER       = SYSTEM_OFF;


    PARKING_BRAKE                    = SYSTEM_OFF;

	
	TURBINE_STARTING_LEFT_TIMER = 0;
    BEACON_LIGHT_POWER               = SYSTEM_OFF;
	NAVIGATION_LIGHTS_POWER          = SYSTEM_OFF;
	STROBE_LIGHTS_POWER              = SYSTEM_OFF;	

	leftstartjet   = 0;
	rightstartjet  = 0;


	skinpath[0] = '\0';
	for (i = 0; i < 3; i++)
		skin[i] = 0;
	for (i = 0; i < 4; i++)
		psngr[i] = false;
	for (i = 0; i < 2; i++) {
		scram_max[i] = 0.0;
		scram_intensity[i] = 0.0;
	}
	for (i = 0; i < 2; i++) {
		scgimbalidx[i] = mpgimbalidx[i] = mygimbalidx[i] = 35;
		scflowidx[i] = 0;
		mainflowidx[i] = retroflowidx[i] = -1;
		scTSFCidx[i] = -1;
		mainpropidx[i] = rcspropidx[i] = scrampropidx[i] = -1;
		mpswitch[i] = myswitch[i] = sgswitch[i] = 0;
	}
	for (i = 0; i < 3; i++)
		for (j = 0; j < 3; j++) rotidx[i][j] = 0;

	mpmode = mymode = spmode = hbmode = hbswitch = 0;
	mainpropmass = rcspropmass = jetpropmass = batpropmass = scrampropmass = -1;
	mainTSFCidx = hoverflowidx = -1;
	hbalanceidx = 28;

	// damage parameters
	bDamageEnabled = (GetDamageModel() != 0);
	bMWSActive = bMWSOn = false;
	lwingstatus = rwingstatus = 1.0;
	hatchfail = 0;
	for (i = 0; i < 4; i++) aileronfail[i] = false;

	DefineAnimations();
	for (i = 0; i < nsurf; i++) srf[i] = 0;

    //battery_charge_001 = -1;

}

// --------------------------------------------------------------
// Destructor
// --------------------------------------------------------------
DeltaGlider::~DeltaGlider ()
{
	//if (scramjet) 
		delete scramjet;
	//if (insignia_tex) oapiDestroySurface(insignia_tex);
	ReleaseSurfaces();
    delete m_nose_oleo_piston;
	delete m_nose_axle;
	delete m_nose_axle_cylinder;
    delete m_nose_axle_piston;
    delete m_nose_gear_wheels;
    delete m_gear_door_rear_02_right;
    delete m_gear_door_rear_02_left;
    delete m_oleo_piston_right_side;
    delete m_axle_right_side;
    delete m_axle_piston_right;
    delete m_wheel_right_rear_right_side;	
    delete m_wheel_right_front_right_side;
    delete m_wheel_left_rear_right_side;	
    delete m_wheel_left_front_right_side;
    
	delete m_oleo_piston_left_side;
    delete m_axle_left_side;
    delete m_axle_piston_left;
    delete m_wheel_right_rear_left_side;	
    delete m_wheel_right_front_left_side;
    delete m_wheel_left_rear_left_side;	
    delete m_wheel_left_front_left_side;
    
	
	delete m_nose_cone_pin;
	
	//airlock
	delete m_inside_tube;
    delete m_outside_tube_002;
    delete m_outter_air_lock;
	
	// air lock outer door
	delete m_outer_air_lock_pedal_001_part_001;
    delete m_outer_air_lock_pedal_001_part_002;
    delete m_outer_air_lock_pedal_001_part_003;
	delete m_outer_air_lock_pedal_002_part_001;
    delete m_outer_air_lock_pedal_003_part_001;
    delete m_outer_air_lock_pedal_004_part_001;
    delete m_outer_air_lock_pedal_005_part_001;
    delete m_outer_air_lock_pedal_006_part_001;
    delete m_outer_air_lock_pedal_007_part_001;
    delete m_outer_air_lock_pedal_008_part_001;
    delete m_outer_air_lock_pedal_009_part_001;
    delete m_outer_air_lock_pedal_010_part_001;
    
    // air lock inner door
	delete m_inner_air_lock_pedal_001_part_001;
    delete m_inner_air_lock_pedal_001_part_002;
    delete m_inner_air_lock_pedal_001_part_003;
	delete m_inner_air_lock_pedal_002_part_001;
    delete m_inner_air_lock_pedal_003_part_001;
    delete m_inner_air_lock_pedal_004_part_001;
    delete m_inner_air_lock_pedal_005_part_001;
    delete m_inner_air_lock_pedal_006_part_001;
    delete m_inner_air_lock_pedal_007_part_001;
    delete m_inner_air_lock_pedal_008_part_001;
    delete m_inner_air_lock_pedal_009_part_001;
    delete m_inner_air_lock_pedal_010_part_001;
    














}

// --------------------------------------------------------------
// Set vessel mass excluding propellants
// --------------------------------------------------------------
void DeltaGlider::SetEmptyMass () const
{
	double emass = (scramjet ? EMPTY_MASS_SC : EMPTY_MASS);
	// add passengers+life support to empty vessel mass
	for (int i = 0; i < 4; i++)
		if (psngr[i]) emass += PSNGR_MASS;

	VESSEL2::SetEmptyMass (emass);
}



// --------------------------------------------------------------
// Release bitmaps used for panel animations
// --------------------------------------------------------------
void DeltaGlider::ReleaseSurfaces ()
{
	for (int i = 0; i < nsurf; i++)
		if (srf[i]) {
			oapiDestroySurface (srf[i]);
			srf[i] = 0;
		}
}

// --------------------------------------------------------------
// Load panel animation bitmaps and initialise panel state
// --------------------------------------------------------------
void DeltaGlider::InitPanel (int panel)
{
	int i;

	switch (panel) {
	case 0: // main panel
		// load bitmaps used by the panel
		srf[0] = oapiCreateSurface (LOADBMP (IDB_SWITCH1));
		srf[1] = oapiCreateSurface (LOADBMP (IDB_NAVBUTTON));
		srf[2] = oapiCreateSurface (LOADBMP (IDB_LIGHT1));
		srf[3] = oapiCreateSurface (LOADBMP (IDB_HORIZON));     oapiSetSurfaceColourKey (srf[3], 0);
		srf[4] = oapiCreateSurface (LOADBMP (IDB_SLIDER1));
		srf[5] = oapiCreateSurface (LOADBMP (IDB_LIGHT2));
		srf[6] = oapiCreateSurface (LOADBMP (IDB_SWITCH4));
		srf[7] = oapiCreateSurface (LOADBMP (IDB_SWITCH4R));
		srf[8] = oapiCreateSurface (LOADBMP (IDB_INDICATOR2));  oapiSetSurfaceColourKey (srf[8], 0);
		srf[9] = oapiCreateSurface (LOADBMP (IDB_DIAL1));
		srf[10] = oapiCreateSurface (LOADBMP (IDB_FONT2));
		srf[11] = oapiCreateSurface (LOADBMP (IDB_WARN));
		srf[12] = oapiCreateSurface (LOADBMP (IDB_CHARGING));
        
		// reset state flags for panel instruments
		for (i = 0; i < 5; i++) engsliderpos[i] = (UINT)-1;
		elevtrimpos = (UINT)-1;
		for (i = 0; i < 2; i++)
			mainflowidx[i] = retroflowidx[i] = scTSFCidx[i] = scflowidx[i] =
			mainpropidx[i] = rcspropidx[i] = scrampropidx[i] = -1;
		mainpropmass = rcspropmass = jetpropmass = batpropmass = scrampropmass = -1;
		hoverflowidx = mainTSFCidx = -1;

        

		memset (&p_prpdisp, 0, sizeof(p_prpdisp));
		memset (&p_engdisp, 0, sizeof(p_engdisp));
		memset (&p_rngdisp, 0, sizeof(p_rngdisp));
		break;
	case 1: // overhead panel
		srf[0] = oapiCreateSurface (LOADBMP (IDB_SWITCH1));
		srf[1] = oapiCreateSurface (LOADBMP (IDB_INDICATOR));
		srf[4] = oapiCreateSurface (LOADBMP (IDB_VPITCH));
		srf[5] = oapiCreateSurface (LOADBMP (IDB_VBANK));
		srf[6] = oapiCreateSurface (LOADBMP (IDB_VYAW));
		srf[7] = oapiCreateSurface (LOADBMP (IDB_SWITCH6));
		srf[8] = oapiCreateSurface (LOADBMP (IDB_START));
		srf[9] = oapiCreateSurface (LOADBMP (IDB_SWITCH_OPEN_CLOSE));
		break;
	case 2: // bottom panel
		srf[0] = oapiCreateSurface (LOADBMP (IDB_SWITCH2));
		srf[1] = oapiCreateSurface (LOADBMP (IDB_LEVER1));
		srf[2] = oapiCreateSurface (LOADBMP (IDB_SWITCH3));
		srf[9] = oapiCreateSurface (LOADBMP (IDB_INDICATOR));
		for (i = 0; i < 2; i++) wbrake_pos[i] = (UINT)-1;
		dockreleasedown = false;
		break;
	
	case 3: // eva panel
	   srf[0] = oapiCreateSurface (LOADBMP (IDB_FONT2));
	   srf[1] = oapiCreateSurface (LOADBMP (IDB_SWITCH5));
	
	   break;

	   case 4: // power panel
	  
	
	   
	
      
	   srf[0] = oapiCreateSurface (LOADBMP (IDB_SWITCH6));
	   



	   break;



	}
}

void DeltaGlider::ScramjetThrust ()
{
	int i;
	const double eps = 1e-8;
	const double Fnominal = 2.5*MAX_MAIN_THRUST[modelidx];

	double Fscram[2];
	scramjet->Thrust (Fscram);

	for (i = 0; i < 2; i++) {
		double level = GetThrusterLevel (th_main[i]);
		double Fmax  = Fscram[i]/(level+eps);
		SetThrusterMax0 (th_main[i], Fmax);
		SetThrusterIsp (th_main[i], max (1.0, Fscram[i]/(scramjet->DMF(i)+eps))); // don't allow ISP=0

		// the following are used for calculating exhaust density
		scram_max[i] = min (Fmax/Fnominal, 1.0);
		scram_intensity[i] = level * scram_max[i];
	}
}


void DeltaGlider::clbkDrawHUD (int mode, const HUDPAINTSPEC *hps, HDC hDC)
{
	// draw the default HUD
	if (HUD_PANEL_ID == 0) VESSEL2::clbkDrawHUD (mode, hps, hDC);
/*
	// show gear deployment status
	if (gear_status == DOOR_OPEN || (gear_status >= DOOR_CLOSING && fmod (oapiGetSimTime(), 1.0) < 0.5)) {
		int d = hps->Markersize/2;
		int cx = hps->CX, cy = hps->CY;
		if (cx >= -d*3 && cx < hps->W+d*3 && cy >= d && cy < hps->H+d*5) {
			Rectangle (hDC, cx-d/2, cy-d*5, cx+d/2, cy-d*4);
			Rectangle (hDC, cx-d*3, cy-d*2, cx-d*2, cy-d);
			Rectangle (hDC, cx+d*2, cy-d*2, cx+d*3, cy-d);
		}
	}
*/
	// show RCS mode
	
}

void DeltaGlider::ActivateLandingGear (DoorStatus action)
{
	if (action == DOOR_OPENING && GroundContact()) return;
	// we cannot deploy the landing gear if we are already sitting on the ground

	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	gear_status = action;
	if (action <= DOOR_OPEN) {
		gear_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		SetAnimation (anim_gear, gear_proc);
		//UpdateStatusIndicators();
		SetGearParameters (gear_proc);
	}
	oapiTriggerPanelRedrawArea (2, AID_GEARSWITCH);
	//oapiTriggerRedrawArea (2, 0, AID_GEARINDICATOR);
	//SetAnimation (anim_gearlever, close ? 0:1);
	RecordEvent ("GEAR", close ? "UP" : "DOWN");
}

void DeltaGlider::RevertLandingGear ()
{
	ActivateLandingGear (gear_status == DOOR_CLOSED || gear_status == DOOR_CLOSING ?
						 DOOR_OPENING : DOOR_CLOSING);
	UpdateCtrlDialog (this);
}

void DeltaGlider::SetGearParameters (double state)
{
	if (state == 1.0) {
		SetTouchdownPoints (_V(0, -5.188098, 12.113704), _V(-5.737381, -5.177002, -6.266663), _V(5.737381, -5.177002, -6.266663));
		SetSurfaceFrictionCoeff (0.05, 0.4);
		SetNosewheelSteering (true);
	} else {
		SetTouchdownPoints (_V(0, -2.86, 12.113704), _V(-5.737381, -2.86, -6.266663), _V(5.737381, -2.86, -6.266663));
		SetSurfaceFrictionCoeff (0.4, 0.4);
		SetNosewheelSteering (false);
	}
}


void DeltaGlider::CHANGE_ENGINE_MODE (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	engine_status = action;
	if (action <= DOOR_OPEN) {
		engine_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		
	}
	oapiTriggerPanelRedrawArea (0, AID_ENGINE_MODE);
	//SetAnimation (anim_radiatorswitch, close ? 0:1);
	//UpdateCtrlDialog (this);
	//RecordEvent ("RADIATOR", close ? "CLOSE" : "OPEN");
}

void DeltaGlider::ActivateNoseCone (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	NOSE_CONE_STATUS = action;
	if (action <= DOOR_OPEN) {
		nose_cone_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		//SetAnimation (anim_nose, nose_cone_proc);
		//UpdateStatusIndicators();
	}
	oapiTriggerPanelRedrawArea (2, AID_NOSECONE);
	//oapiTriggerRedrawArea (2, 0, AID_NOSECONEINDICATOR);
	//SetAnimation (anim_nconelever, close ? 0:1);

	if (close && ladder_status != DOOR_CLOSED)
		ActivateLadder (action); // retract ladder before closing the nose cone

	UpdateCtrlDialog (this);
	RecordEvent ("NOSECONE", close ? "CLOSE" : "OPEN");
}

void DeltaGlider::ExtendAirLock (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	AIRLOCK_TUBE_STATUS = action;
	if (action <= DOOR_OPEN) {
		air_lock_tube_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		//SetAnimation (anim_nose, nose_cone_proc);
		//UpdateStatusIndicators();
	}
	//oapiTriggerPanelRedrawArea (2, AID_NOSECONE);
	//oapiTriggerRedrawArea (2, 0, AID_NOSECONEINDICATOR);
	//SetAnimation (anim_nconelever, close ? 0:1);

	
}

void DeltaGlider::ActivateHatch (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	if (hatch_status == DOOR_CLOSED && !close && !hatch_vent && GetAtmPressure() < 10e3) {
		static PARTICLESTREAMSPEC airvent = {
			0, 1.0, 15, 0.5, 0.3, 2, 0.3, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
			PARTICLESTREAMSPEC::LVL_LIN, 0.1, 0.1,
			PARTICLESTREAMSPEC::ATM_FLAT, 0.1, 0.1
		};
		static VECTOR3 pos = {0,2,4};
		static VECTOR3 dir = {0,1,0};
		static double lvl = 0.1;
		hatch_vent = AddParticleStream (&airvent, pos, dir, &lvl);
		hatch_vent_t = oapiGetSimTime();
	}

	hatch_status = action;
	if (action <= DOOR_OPEN) {
		hatch_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		//SetAnimation (anim_hatch, hatch_proc);
		//UpdateStatusIndicators();
	}
	oapiTriggerPanelRedrawArea (0, AID_HATCHSWITCH);
	//SetAnimation (anim_hatchswitch, close ? 0:1);
	UpdateCtrlDialog (this);
	RecordEvent ("HATCH", close ? "CLOSE" : "OPEN");
}

void DeltaGlider::RevertHatch ()
{
	ActivateHatch (hatch_status == DOOR_CLOSED || hatch_status == DOOR_CLOSING ?
				   DOOR_OPENING : DOOR_CLOSING);
}

void DeltaGlider::ActivateLadder (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	if (!close && NOSE_CONE_STATUS != DOOR_OPEN) return;
	// don't extend ladder if nose cone is closed

	ladder_status = action;
	if (action <= DOOR_OPEN) {
		ladder_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		SetAnimation (anim_ladder, ladder_proc);
	}
	oapiTriggerPanelRedrawArea (0, AID_LADDERSWITCH);
	//SetAnimation (anim_ladderswitch, close ? 0:1);
	UpdateCtrlDialog (this);
	RecordEvent ("LADDER", close ? "CLOSE" : "OPEN");
}

void DeltaGlider::RevertLadder ()
{
	ActivateLadder (ladder_status == DOOR_CLOSED || ladder_status == DOOR_CLOSING ?
					DOOR_OPENING : DOOR_CLOSING);
}

void DeltaGlider::ActivateOuterAirlock (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	OUTER_AIRLOCK_DOOR_STATUS = action;
	if (action <= DOOR_OPEN) {
		outer_air_lock_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		//SetAnimation (anim_olock, outer_air_lock_proc);
		//UpdateStatusIndicators();
	}
	//oapiTriggerPanelRedrawArea (1, AID_OUTER_AIRLOCK_DOOR);
	//SetAnimation (anim_olockswitch, close ? 0:1);
	UpdateCtrlDialog (this);
	RecordEvent ("OLOCK", close ? "CLOSE" : "OPEN");
}

void DeltaGlider::RevertOuterAirlock ()
{
	ActivateOuterAirlock (OUTER_AIRLOCK_DOOR_STATUS == DOOR_CLOSED || OUTER_AIRLOCK_DOOR_STATUS == DOOR_CLOSING ?
		                  DOOR_OPENING : DOOR_CLOSING);
}

void DeltaGlider::ActivateInnerAirlock (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	INNER_AIRLOCK_DOOR_STATUS = action;
	if (action <= DOOR_OPEN) {
		inner_air_lock_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		SetAnimation (anim_ilock, inner_air_lock_proc);
		//UpdateStatusIndicators();
	}
	oapiTriggerPanelRedrawArea (1, AID_INNER_AIRLOCK_DOOR);
	//SetAnimation (anim_ilockswitch, close ? 0:1);
	UpdateCtrlDialog (this);
	RecordEvent ("ILOCK", close ? "CLOSE" : "OPEN");
}

void DeltaGlider::RevertInnerAirlock ()
{
	ActivateInnerAirlock (INNER_AIRLOCK_DOOR_STATUS == DOOR_CLOSED || INNER_AIRLOCK_DOOR_STATUS == DOOR_CLOSING ?
		                  DOOR_OPENING : DOOR_CLOSING);
}

void DeltaGlider::ActivateAirbrake (DoorStatus action)
{
	brake_status = action;
	RecordEvent ("AIRBRAKE", action == DOOR_CLOSING ? "CLOSE" : "OPEN");
}

void DeltaGlider::RevertAirbrake (void)
{
	ActivateAirbrake (brake_status == DOOR_CLOSED || brake_status == DOOR_CLOSING ?
		DOOR_OPENING : DOOR_CLOSING);
}

void DeltaGlider::ActivateRadiator (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	radiator_status = action;
	if (action <= DOOR_OPEN) {
		radiator_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		//SetAnimation (anim_radiator, radiator_proc);
		//UpdateStatusIndicators();
	}
	oapiTriggerPanelRedrawArea (0, AID_RADIATORSWITCH);
	//SetAnimation (anim_radiatorswitch, close ? 0:1);
	UpdateCtrlDialog (this);
	RecordEvent ("RADIATOR", close ? "CLOSE" : "OPEN");
}

void DeltaGlider::ActivateReverser (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	REVERSER_STSTUS = action;
	if (action <= DOOR_OPEN) {
		reverser_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		SetAnimation (anim_reverser, reverser_proc);
		
	}

   
	
}

void DeltaGlider::Activate_bay_door_forward_right (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	BAY_DOOR_FORWARD_RIGHT_STATUS = action;
	if (action <= DOOR_OPEN) {
		bay_door_forward_right_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		SetAnimation (anim_bay_door_forward_right, bay_door_forward_right_proc);
	}
}

void DeltaGlider::Activate_bay_door_forward_left (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	BAY_DOOR_FORWARD_LEFT_STATUS = action;
	if (action <= DOOR_OPEN) {
		bay_door_forward_left_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		SetAnimation (anim_bay_door_forward_left, bay_door_forward_left_proc);
	}
}

void DeltaGlider::Activate_bay_door_aft_right (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	BAY_DOOR_AFT_RIGHT_STATUS = action;
	if (action <= DOOR_OPEN) {
		bay_door_aft_right_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		SetAnimation (anim_bay_door_aft_right, bay_door_aft_right_proc);
	}
}

void DeltaGlider::Activate_bay_door_aft_left (DoorStatus action)
{
	bool close = (action == DOOR_CLOSED || action == DOOR_CLOSING);
	BAY_DOOR_AFT_LEFT_STATUS = action;
	if (action <= DOOR_OPEN) {
		bay_door_aft_left_proc = (action == DOOR_CLOSED ? 0.0 : 1.0);
		SetAnimation (anim_bay_door_aft_left, bay_door_aft_left_proc);
	}
}

void DeltaGlider::RevertReverser (void)
{
	ActivateReverser (REVERSER_STSTUS == DOOR_CLOSED || REVERSER_STSTUS == DOOR_CLOSING ?
		DOOR_OPENING : DOOR_CLOSING);

}




void DeltaGlider::RevertRadiator (void)
{
	ActivateRadiator (radiator_status == DOOR_CLOSED || radiator_status == DOOR_CLOSING ?
		DOOR_OPENING : DOOR_CLOSING);
}

void DeltaGlider::SetNavlight (bool on)
{
	beacon[0].active = beacon[1].active = beacon[2].active = on;
	oapiTriggerPanelRedrawArea (1, AID_NAVIGATION_SWITCH);
	UpdateCtrlDialog (this);
}

void DeltaGlider::SetBeacon (bool on)
{
	beacon[3].active = beacon[4].active = on;
	oapiTriggerPanelRedrawArea (1, AID_BEACON_SWITCH);
	UpdateCtrlDialog (this);
}

void DeltaGlider::SetStrobe (bool on)
{
	beacon[5].active = beacon[6].active = on;
	oapiTriggerPanelRedrawArea (1, AID_STROBE_SWITCH);
	UpdateCtrlDialog (this);
}

bool DeltaGlider::DecAttMode ()
{
	int mode = GetAttitudeMode();
	if (mode) {
		SetAttitudeMode (mode-1);
		return true;
	} else return false;
}

bool DeltaGlider::IncAttMode ()
{
	int mode = GetAttitudeMode();
	if (mode < 2) {
		SetAttitudeMode (mode+1);
		return true;
	} else return false;
}

bool DeltaGlider::DecADCMode ()
{
	DWORD mode = min (GetADCtrlMode(),2);
	if (mode) {
		SetADCtrlMode (mode-1);
		return true;
	} else return false;
}

bool DeltaGlider::IncADCMode ()
{
	DWORD mode = GetADCtrlMode();
	if (mode <= 1) {
		SetADCtrlMode (mode ? 7 : 1);
		return true;
	} else return false;
}

void DeltaGlider::SetMainRetroLevel (int which, double lmain, double lretro)
{
	if (which == 2) {   // set main thruster group
		SetThrusterGroupLevel (THGROUP_MAIN,  lmain);
		SetThrusterGroupLevel (THGROUP_RETRO, lretro);
	} else {            // set individual engine
		SetThrusterLevel (th_main [which], lmain);
		SetThrusterLevel (th_retro[which], lretro);
	}
}

void DeltaGlider::SetScramLevel (int which, double level)
{
	for (int i = 0; i < 2; i++) {
		if (which != 1-i) {
			SetThrusterLevel (th_main[i], level);
			scram_intensity[i] = level * scram_max[i];
		}
	}
}



bool DeltaGlider::ShiftHoverBalance (int mode)
{
	hbswitch = mode;
	double t0 = GetThrusterMax0 (th_hover[0]);
	double t1 = GetThrusterMax0 (th_hover[1]);
	double dt = t0-t1;
	if (mode) {
		double shift = oapiGetSimStep() * HOVER_BALANCE_SPEED * (mode == 1 ? 1.0:-1.0);
		dt = max (min (dt+shift, MAX_HOVER_IMBALANCE), -MAX_HOVER_IMBALANCE);
		SetThrusterMax0 (th_hover[0], MAX_HOVER_THRUST[modelidx] + dt*0.5);
		SetThrusterMax0 (th_hover[1], MAX_HOVER_THRUST[modelidx] - dt*0.5);
	}
	int idx = (int)(28.4999*(1.0-dt/MAX_HOVER_IMBALANCE));
	if (idx != hbalanceidx) {
		hbalanceidx = idx;
		return true;
	} else
		return false;
}

bool DeltaGlider::IncMainPGimbal (int which, int mode)
{
	VECTOR3 dir;
	int i, idx;
	bool redraw = false;
	double dy = oapiGetSimStep() * MAIN_PGIMBAL_SPEED * (mode == 1 ? -1.0:1.0);

	for (i = 0; i < 2; i++) {
		if (mode && which & (1 << i)) {
			GetThrusterDir (th_main[i], dir);
			dir /= dir.z;
			dir.y = min (MAIN_PGIMBAL_RANGE, max (-MAIN_PGIMBAL_RANGE, dir.y+dy));
			SetThrusterDir (th_main[i], dir);
			idx = (int)(35.4999*(dir.y/MAIN_PGIMBAL_RANGE+1.0));
			if (idx != mpgimbalidx[i]) {
				mpgimbalidx[i] = idx;
				redraw = true;
			}
			mpswitch[i] = mode;
		} else
			mpswitch[i] = 0;
	}
	return redraw;
}

void DeltaGlider::AdjustMainPGimbal (int &mode)
{
	VECTOR3 dir;
	int i, idx;
	double dy = oapiGetSimStep() * MAIN_PGIMBAL_SPEED;
	bool keep_going = false;

	if (mode == 1) {
		for (i = 0; i < 2; i++) {
			GetThrusterDir (th_main[i], dir);
			dir /= dir.z;
			if (dir.y >= 0.0) dir.y = max(0.0, dir.y - dy);
			else              dir.y = min(0.0, dir.y + dy);
			SetThrusterDir (th_main[i], dir);
			idx = (int)(35.5*(dir.y/MAIN_PGIMBAL_RANGE+1.0));
			if (idx != mpgimbalidx[i]) {
				mpgimbalidx[i] = idx;
				oapiTriggerRedrawArea (0, 0, AID_PGIMBALMAINDISP);
			}
			if (dir.y) keep_going = true;
		}
		if (!keep_going) {
			mode = 0;
			oapiTriggerRedrawArea (0, 0, AID_PGIMBALMAINMODE);
		}
	}
}

bool DeltaGlider::IncMainYGimbal (int which, int mode)
{
	VECTOR3 dir;
	int i, idx;
	bool redraw = false;
	double dx = oapiGetSimStep() * MAIN_YGIMBAL_SPEED * (mode == 1 ? 1.0:-1.0);

	for (i = 0; i < 2; i++) {
		if (mode && which & (1 << i)) {
			GetThrusterDir (th_main[i], dir);
			dir /= dir.z;
			dir.x = min (MAIN_YGIMBAL_RANGE, max (-MAIN_YGIMBAL_RANGE, dir.x+dx));
			SetThrusterDir (th_main[i], dir);
			idx = (int)(35.4999*(1.0-dir.x/MAIN_YGIMBAL_RANGE));
			if (idx != mygimbalidx[i]) {
				mygimbalidx[i] = idx;
				redraw = true;
			}
			myswitch[i] = mode;
		} else
			myswitch[i] = 0;
	}
	return redraw;
}

void DeltaGlider::AdjustMainYGimbal (int &mode)
{
	VECTOR3 dir;
	int i, idx;
	double tgtx[2], dx = oapiGetSimStep() * MAIN_YGIMBAL_SPEED;
	bool keep_going = false;

	switch (mode) {
	case 1:   // center
		tgtx[0] = tgtx[1] = 0.0;
		break;
	case 2:   // divergent
		tgtx[1] = -(tgtx[0] = MAIN_YGIMBAL_RANGE);
		break;
	case 3: { // auto adjust
		double t0 = GetThrusterLevel (th_main[0]);
		double t1 = GetThrusterLevel (th_main[1]);
		double tt = t0+t1;
		tgtx[0] = tgtx[1] = (tt ? MAIN_YGIMBAL_RANGE*(t0-t1)/tt : 0.0);
		} break;
	}

	for (i = 0; i < 2; i++) {
		GetThrusterDir (th_main[i], dir);
		dir /= dir.z;
		if (dir.x >= tgtx[i]) dir.x = max(tgtx[i], dir.x - dx);
		else                  dir.x = min(tgtx[i], dir.x + dx);
		if (dir.x != tgtx[i] || mode == 3) keep_going = true;
		SetThrusterDir (th_main[i], dir);
		idx = (int)(35.4999*(1.0-dir.x/MAIN_YGIMBAL_RANGE));
		if (idx != mygimbalidx[i]) {
			mygimbalidx[i] = idx;
			oapiTriggerRedrawArea (0, 0, AID_YGIMBALMAINDISP);
		}
	}
	if (!keep_going) {
		mode = 0;
		oapiTriggerRedrawArea (0, 0, AID_YGIMBALMAINMODE);
	}
}

bool DeltaGlider::IncScramGimbal (int which, int mode)
{
	VECTOR3 dir;
	int i, idx;
	bool redraw = false;
	double phi, dphi = oapiGetSimStep() * SCRAM_GIMBAL_SPEED * (mode == 1 ? -1.0:1.0);

	for (i = 0; i < 2; i++) {
		if (mode && which & (1 << i)) {
			GetThrusterDir (th_main[i], dir);
			phi = atan2 (dir.y, dir.z);
			phi = min (SCRAM_DEFAULT_DIR+SCRAM_GIMBAL_RANGE, max (SCRAM_DEFAULT_DIR-SCRAM_GIMBAL_RANGE, phi+dphi));
			SetThrusterDir (th_main[i], _V(0, sin(phi), cos(phi)));
			idx = (int)(35.5*(phi-SCRAM_DEFAULT_DIR+SCRAM_GIMBAL_RANGE)/SCRAM_GIMBAL_RANGE);
			if (idx != scgimbalidx[i]) {
				scgimbalidx[i] = idx;
				redraw = true;
			}
			sgswitch[i] = mode;
		} else
			sgswitch[i] = 0;
	}
	return redraw;
}

void DeltaGlider::AdjustScramGimbal (int &mode)
{
	VECTOR3 dir;
	int i, idx;
	double phi, dphi = oapiGetSimStep() * SCRAM_GIMBAL_SPEED;
	bool keep_going = false;

	if (mode == 1) {
		for (i = 0; i < 2; i++) {
			GetThrusterDir (th_main[i], dir);
			phi = atan2 (dir.y, dir.z);
			if (phi >= SCRAM_DEFAULT_DIR) phi = max(SCRAM_DEFAULT_DIR, phi - dphi);
			else                          phi = min(SCRAM_DEFAULT_DIR, phi + dphi);
			SetThrusterDir (th_main[i], _V(0, sin(phi), cos(phi)));
			idx = (int)(35.5*(phi-SCRAM_DEFAULT_DIR+SCRAM_GIMBAL_RANGE)/SCRAM_GIMBAL_RANGE);
			if (idx != scgimbalidx[i]) {
				scgimbalidx[i] = idx;
				oapiTriggerRedrawArea (0, 0, AID_GIMBALSCRAMDISP);
			}
			if (phi != SCRAM_DEFAULT_DIR) keep_going = true;
		}
		if (!keep_going) {
			mode = 0;
			oapiTriggerRedrawArea (0, 0, AID_GIMBALSCRAMMODE);
		}
	}
}

void DeltaGlider::AdjustHoverBalance (int &mode)
{
	if (mode == 1) {
		double t0 = GetThrusterMax0 (th_hover[0]);
		double t1 = GetThrusterMax0 (th_hover[1]);
		double dt = t0-t1;
		double shift = oapiGetSimStep() * HOVER_BALANCE_SPEED;
		if (dt >= 0.0) dt = max (0.0, dt-shift);
		else           dt = min (0.0, dt+shift);
		SetThrusterMax0 (th_hover[0], MAX_HOVER_THRUST[modelidx] + dt*0.5);
		SetThrusterMax0 (th_hover[1], MAX_HOVER_THRUST[modelidx] - dt*0.5);
		int idx = (int)(28.4999*(1.0-dt/MAX_HOVER_IMBALANCE));
		if (idx != hbalanceidx) {
			hbalanceidx = idx;
			oapiTriggerRedrawArea (0, 0, AID_HBALANCEDISP);
		}
		if (dt == 0.0) {
			mode = 0;
			oapiTriggerRedrawArea (0, 0, AID_HBALANCEMODE);
		}
	}
}

void DeltaGlider::ApplyDamage ()
{
	double balance = (rwingstatus-lwingstatus)*3.0;
	double surf    = (rwingstatus+lwingstatus)*35.0 + 20.0;
	EditAirfoil (hwing, 0x09, _V(balance,0,-0.3), 0, 0, surf, 0);

	if (rwingstatus < 1 || lwingstatus < 1) bMWSActive = true;

	//SetDamageVisuals();
}

void DeltaGlider::RepairDamage ()
{
	int i;
	lwingstatus = rwingstatus = 1.0;
	EditAirfoil (hwing, 0x09, _V(0,0,-0.3), 0, 0, 90.0, 0);
	if (!hlaileron)
		hlaileron = CreateControlSurface2 (AIRCTRL_AILERON, 0.3, 1.5, _V( 7.5,0,-7.2), AIRCTRL_AXIS_XPOS, anim_raileron);
	if (!hraileron)
		hraileron = CreateControlSurface2 (AIRCTRL_AILERON, 0.3, 1.5, _V(-7.5,0,-7.2), AIRCTRL_AXIS_XNEG, anim_laileron);
	for (i = 0; i < 4; i++)
		aileronfail[i] = false;
	hatchfail = 0;
	bMWSActive = bMWSOn = false;
	oapiTriggerRedrawArea (0,0, AID_MWS);
	//UpdateDamageDialog (this);
//	SetDamageVisuals();
}




bool DeltaGlider::Redraw_Environmental_Control (SURFHANDLE surf)
{
char cbuf[20];
	

//page 0 start
if (Environmental_Control_Computer_page == 0)
	{
	HDC hDC = oapiGetDC (surf);
	SelectObject (hDC, g_Param.font[2]);
    SetTextColor (hDC, RGB(254,254,254));
	SetBkMode (hDC, TRANSPARENT);
    TextOut (hDC, 0, 0, "Cabin Temperature", 17); 
	TextOut (hDC, 0, 11, "Co   filter 1: ", 15);
    TextOut (hDC, 0, 22, "Co   filter 2: ", 15);
	TextOut (hDC, 0, 33, "Radiator Temperatures", 21);
	TextOut (hDC, 0, 44, "Radiator Loop A", 15);    TextOut (hDC, 105, 44, "B", 1);
	TextOut (hDC, 0, 55, "Radiator Loop C", 15);    TextOut (hDC, 105, 55, "D", 1);
    TextOut (hDC, 0, 66, "< > Page", 8);
    SelectObject (hDC, g_Param.font[3]);
	TextOut (hDC, 12, 18, "2", 1);
    TextOut (hDC, 12, 29, "2", 1);
	SelectObject (hDC, g_Param.font[2]);
	
	if (CabinTemp > 100)                      SetTextColor (hDC, RGB(255,0,0));
	if ((CabinTemp > 95)&& (CabinTemp < 100)) SetTextColor (hDC, RGB(243,252,0));
	if ((CabinTemp < 95)&& (CabinTemp > 72))  SetTextColor (hDC, RGB(128,182,54));
	if (CabinTemp < 72)                       SetTextColor (hDC, RGB(154,218,251));
	
	    
        sprintf (cbuf, "%0.0f", CabinTemp);
		TextOut (hDC, 95, 0, cbuf, strlen(cbuf));
	    SetTextColor (hDC, RGB(128,182,54));
		 //cbuf[20];
        sprintf (cbuf, "%0.2f", carbon_dioxide_level_001);
		TextOut (hDC, 56, 11, cbuf, strlen(cbuf));
	    //cbuf[20];
        sprintf (cbuf, "%0.2f", carbon_dioxide_level_002);
		TextOut (hDC, 56, 22, cbuf, strlen(cbuf));
       // cbuf[20];
        sprintf (cbuf, "%0.0f", RadiatorTemp1);
		TextOut (hDC, 80, 44, cbuf, strlen(cbuf));
        //cbuf[20];
        sprintf (cbuf, "%0.0f", RadiatorTemp3);
		TextOut (hDC, 80, 55, cbuf, strlen(cbuf));
        
        sprintf (cbuf, "%0.0f", RadiatorTemp2);
		TextOut (hDC, 115, 44, cbuf, strlen(cbuf));
        //cbuf[20];
        sprintf (cbuf, "%0.0f", RadiatorTemp4);
		TextOut (hDC, 115, 55, cbuf, strlen(cbuf));
        SetTextColor (hDC, RGB(254,254,254));
        //cbuf[20];
        sprintf (cbuf, "%01d", Environmental_Control_Computer_page );
		TextOut (hDC, 50, 66, cbuf, strlen(cbuf));
        
	oapiReleaseDC (surf, hDC);
	}
//page 0 end

//page 1 start
    if (Environmental_Control_Computer_page == 1)
	{

     HDC hDC = oapiGetDC (surf);
	SelectObject (hDC, g_Param.font[1]);
    SetTextColor (hDC, RGB(254,254,254));
	SetBkMode (hDC, TRANSPARENT);

   TextOut (hDC, 0, 0, "Cabin Temperature", 17);
    
  if (CabinTemp > 100)                      SetTextColor (hDC, RGB(255,0,0));
	if ((CabinTemp > 95)&& (CabinTemp < 100)) SetTextColor (hDC, RGB(243,252,0));
	if ((CabinTemp < 95)&& (CabinTemp > 72))  SetTextColor (hDC, RGB(128,182,54));
	if (CabinTemp < 72)                       SetTextColor (hDC, RGB(154,218,251));
	
	   
        sprintf (cbuf, "%0.0f", CabinTemp);
		TextOut (hDC, 95, 0, cbuf, strlen(cbuf));
	    
        SelectObject (hDC, g_Param.font[1]);
		SetTextColor (hDC, RGB(254,254,254));

     TextOut (hDC, 0, 22, "Set Temperature  < >", 20);
       
        sprintf (cbuf, "%0.0f", CabinThermostatSet);
		TextOut (hDC, 110, 22, cbuf, strlen(cbuf)); 
	   
	 TextOut (hDC, 0, 33, "Cooling Loop", 12); TextOut (hDC, 86, 33, "< >", 3);
	 TextOut (hDC, 0, 44, "BUS", 3);           TextOut (hDC, 86, 44, "< >", 3);
	 SetTextColor (hDC, RGB(154,218,255));
	if (Radiator_loop == 1) TextOut (hDC, 110, 33, "A", 1);
	if (Radiator_loop == 2) TextOut (hDC, 110, 33, "B", 1); 
    if (Radiator_loop == 3) TextOut (hDC, 110, 33, "C", 1);
    if (Radiator_loop == 4) TextOut (hDC, 110, 33, "D", 1);
    
	SetTextColor (hDC, RGB(255,1,1));
    
	if (CabinThermostat_battery_loop == 1) TextOut (hDC, 110, 44, "A", 1);
    if (CabinThermostat_battery_loop == 2) TextOut (hDC, 110, 44, "B", 1);
    if (CabinThermostat_battery_loop == 3) TextOut (hDC, 110, 44, "C", 1);
    if (CabinThermostat_battery_loop == 4) TextOut (hDC, 110, 44, "D", 1);

	  SetTextColor (hDC, RGB(254,254,254));
	  SelectObject (hDC, g_Param.font[2]);
	  SetTextColor (hDC, RGB(254,254,254));
	  TextOut (hDC, 0, 66, "< > Page", 8);
      sprintf (cbuf, "%01d", Environmental_Control_Computer_page );
	  TextOut (hDC, 50, 66, cbuf, strlen(cbuf));

	  oapiReleaseDC (surf, hDC);
	}
//page 1 end

//page 2 start
if (Environmental_Control_Computer_page == 2)
	{
 HDC hDC = oapiGetDC (surf);
	SelectObject (hDC, g_Param.font[1]);
    SetTextColor (hDC, RGB(254,254,254));
	SetBkMode (hDC, TRANSPARENT);

	
	
	
	
	
	
	
	
	
	
	
	
	SelectObject (hDC, g_Param.font[2]);
	  SetTextColor (hDC, RGB(254,254,254));
	  TextOut (hDC, 0, 66, "< > Page", 8);
      sprintf (cbuf, "%01d", Environmental_Control_Computer_page );
	  TextOut (hDC, 50, 66, cbuf, strlen(cbuf));

 oapiReleaseDC (surf, hDC);
	}














	return true;
}






bool DeltaGlider::Redraw_Crew_Member_Name(SURFHANDLE surf)
{
    totalcrew  =  Crew.GetCrewTotalNumber();
	HDC hDC = oapiGetDC (surf);
	SelectObject (hDC, g_Param.hFont[1]);
    if (totalcrew > 0) SetTextColor (hDC, RGB(128,182,54));
	if (totalcrew == 0) SetTextColor (hDC, RGB(255,0,0));
	SetBkMode (hDC, TRANSPARENT);
    	
	char * Name = Crew.GetCrewNameBySlotNumber(SelectedUmmuMember);
   
	
	
	if (totalcrew == 0) 
	{
		TextOut (hDC, 1, 0, "No one is on board", 18); //TextOut (hDC, 15, 1, cbuf, strlen(cbuf));
	}	

	else 
	{
	TextOut (hDC, 1, 0, Name, strlen(Name)); //TextOut (hDC, 15, 1, cbuf, strlen(cbuf));
	} 
	oapiReleaseDC (surf, hDC);



return true;



}


bool DeltaGlider::Redraw_Crew_Total_Number (SURFHANDLE surf)
{
int m = Crew.GetCrewTotalNumber();
	
char cbuf[8];
		
		sprintf (cbuf, "%01d", m); //"%05d"
		return  RedrawPanel_Number_1 (surf, 0, 0, cbuf); //RedrawPanel_Number
	return true;
	} 

bool DeltaGlider::Redraw_Cargo_Name(SURFHANDLE surf)
{
	HDC hDC = oapiGetDC (surf);
	SelectObject (hDC, g_Param.hFont[1]);
	SetTextColor (hDC, RGB(128,182,54));
	SetBkMode (hDC, TRANSPARENT);
	
	if (SelectedCrgo == totalcargo -1 )SelectedCrgo = 0;
    if (SelectedCrgo ==  -1) SelectedCrgo = totalcargo -1  ;
	
	
    OBJHANDLE myhandle = oapiGetVesselByIndex (SelectedCrgo); 
    oapiGetObjectName(myhandle, Name, sizeof(Name)); 
	
	GetRelativePos(myhandle, Cargo_Position);
	/*
	{ 
	if (myhandle == GetHandle()) // don't want our name
	//if ((myhandle == GetHandle()) || (length(Cargo_Position) > CARGO_MAX_DIST)) // don't want our name
  {  
    TextOut (hDC, 1, 0, "Cargo out of range ", 18); //TextOut (hDC, 15, 1, cbuf, strlen(cbuf));
	
   if (cargoUpDown == 0) SelectedCrgo = SelectedCrgo - 1;
   if (cargoUpDown == 1) SelectedCrgo = SelectedCrgo + 1;
   
   cargoUpDown = 2;
  }
  else
  {
	  TextOut (hDC, 1, 0, Name, strlen(Name)); //TextOut (hDC, 15, 1, cbuf, strlen(cbuf));
  }
 
  oapiReleaseDC (surf, hDC);
	
	}

*/

TextOut (hDC, 1, 0, Name, strlen(Name)); //TextOut (hDC, 15, 1, cbuf, strlen(cbuf)); // Kludg 
  oapiReleaseDC (surf, hDC);


return true;



}

void DeltaGlider::Grapple_Cargo()
{

	//ATTACHMENTHANDLE hAtt = v->GetAttachmentHandle (true, j);
	//AttachChild (myhandle, payload_attachment[0], hAtt);

}



//----------------------------new --------------------------------


bool DeltaGlider::Redraw_Enter_Airlock (SURFHANDLE surf)
{

	HDC hDC = oapiGetDC (surf);
	SelectObject (hDC, g_Param.hFont[1]);
	if (OUTER_AIRLOCK_DOOR_STATUS == DOOR_OPEN )SetTextColor (hDC, RGB(128,182,54));
	if (OUTER_AIRLOCK_DOOR_STATUS == DOOR_CLOSED )SetTextColor (hDC, RGB(255,0,0));
	if (OUTER_AIRLOCK_DOOR_STATUS == DOOR_CLOSING ) SetTextColor (hDC, RGB(255,255,0));
	if (OUTER_AIRLOCK_DOOR_STATUS == DOOR_OPENING ) SetTextColor (hDC, RGB(255,255,0));
	SetBkMode (hDC, TRANSPARENT);
    	
    	

    if (OUTER_AIRLOCK_DOOR_STATUS == DOOR_OPEN )TextOut (hDC, 1, 0, "Deploy", 6); //TextOut (hDC, 15, 1, cbuf, strlen(cbuf));
	if (OUTER_AIRLOCK_DOOR_STATUS == DOOR_CLOSED )TextOut (hDC, 1, 0, "Outer Air Lock Door Closed", 26);
	if (OUTER_AIRLOCK_DOOR_STATUS == DOOR_CLOSING )TextOut (hDC, 1, 0, "Outer Air Lock Door Closing", 27);
	if (OUTER_AIRLOCK_DOOR_STATUS == DOOR_OPENING )TextOut (hDC, 1, 0, "Outer Air Lock Door Opening", 27);
	//TextOut (hDC, 1, 0, "Enter Air Lock", 14); //TextOut (hDC, 15, 1, cbuf, strlen(cbuf));
	
	oapiReleaseDC (surf, hDC);




return true;



}





bool DeltaGlider::RedrawPanel_AOA (SURFHANDLE surf, bool force)
{
	static const double dial_max = RAD*165.0;
	static const double eps = 1e-2;

	double aoa = GetAOA();
	double dial_angle = PI - min (dial_max, max (-dial_max, aoa*7.7));
	if (force || fabs(dial_angle-aoa_ind) > eps) {
		oapiBltPanelAreaBackground (AID_AOAINSTR, surf);
		HDC hDC = oapiGetDC (surf);
		DrawNeedle (hDC, 28, 28, 26.0, dial_angle, &aoa_ind);
		oapiReleaseDC (surf, hDC);
		return true;
	} else return false;
}

bool DeltaGlider::RedrawPanel_Slip (SURFHANDLE surf, bool force)
{
	static const double dial_max = RAD*165.0;
	static const double eps = 1e-2;

	double slip = GetSlipAngle();
	double dial_angle = PI05 - min (dial_max, max (-dial_max, slip*7.7));
	if (force || fabs(dial_angle-slip_ind) > eps) {
		oapiBltPanelAreaBackground (AID_SLIPINSTR, surf);
		HDC hDC = oapiGetDC (surf);
		DrawNeedle (hDC, 28, 28, 26.0, dial_angle, &slip_ind);
		oapiReleaseDC (surf, hDC);
		return true;
	} else return false;
}

bool DeltaGlider::RedrawPanel_Wingload (SURFHANDLE surf, bool force)
{
	static const double dial_min = -123.0*RAD;
	static const double dial_max =  217.0*RAD;
	static const double eps = 1e-2;

	double load = GetLift() / 190.0; // L/S
	double dial_angle = PI - min (dial_max, max (dial_min, load/15.429e3*PI));
	if (force || fabs (dial_angle-load_ind) > eps) {
		oapiBltPanelAreaBackground (AID_LOADINSTR, surf);
		HDC hDC = oapiGetDC (surf);
		DrawNeedle (hDC, 28, 28, 26.0, dial_angle, &load_ind);
		oapiReleaseDC (surf, hDC);
		return true;
	} else return false;
}

void DeltaGlider::RedrawPanel_Navmode (SURFHANDLE surf)
{
	static int navx[7] = {0,117,39,39,78,78,117};
	static int navy[7] = {0,0,0,39,0,39,39};
	for (DWORD i = NAVMODE_KILLROT; i <= NAVMODE_HOLDALT; i++)
		if (GetNavmodeState (i))
				//oapiBlt (surf, srf[1], ((i-1)/2) * 39, ((i-1)%2) * 39, (i-1)*37, 0, 37, 37);
				oapiBlt (surf, srf[1], navx[i-1], navy[i-1], (i-1)*37, 0, 37, 37);
}

bool DeltaGlider::RedrawPanel_Throttle (SURFHANDLE surf)
{
	UINT i, pos;
	bool redraw = false;

	for (i = 0; i < 2; i++) {
		double level = GetThrusterLevel (th_main[i]);
		if (level > 0) pos = (UINT)((1.0-level)*108.0);
		else {
			level = GetThrusterLevel (th_retro[i]);
			if (level > 0) pos = 125+(UINT)(level*32.0);
			else           pos = 116;
		}
		if (pos != engsliderpos[i])
			engsliderpos[i] = pos, redraw = true;
	}
	if (redraw) {
		oapiBltPanelAreaBackground (AID_ENGINEMAIN, surf);
		for (i = 0; i < 2; i++)
			oapiBlt (surf, srf[4], i*26, engsliderpos[i], 0, 0, 23, 18);
	}
	return redraw;
}

bool DeltaGlider::RedrawPanel_ThHover (SURFHANDLE surf)
{
	double level = GetThrusterLevel (th_hover[0]);
	UINT pos = (UINT)((1.0-level)*116.0);
	if (pos != engsliderpos[2]) {
		oapiBltPanelAreaBackground (AID_ENGINEHOVER, surf);
		oapiBlt (surf, srf[4], 0, engsliderpos[2] = pos, 0, 0, 23, 18);
		return true;
	} else return false;
}

bool DeltaGlider::RedrawPanel_ThScram (SURFHANDLE surf)
{
	UINT i, pos;
	bool redraw = false;

	for (i = 0; i < 2; i++) {
		double level = GetThrusterLevel (th_main[i]);
		pos = (UINT)((1.0-level)*84.0);
		if (pos != engsliderpos[i+3])
			engsliderpos[i+3] = pos, redraw = true;
	}
	if (redraw) {
		oapiBltPanelAreaBackground (AID_ENGINESCRAM, surf);
		for (i = 0; i < 2; i++)
			oapiBlt (surf, srf[4], i*26, engsliderpos[i+3], 0, 0, 23, 18);
	}
	return redraw;
}

bool DeltaGlider::RedrawPanel_ScramTSFC (SURFHANDLE surf)
{
	bool redraw = false;
	for (int i = 0; i < 2; i++) {
		int p = min (66, (int)(scramjet->TSFC(i)*(1e3*66.0/0.03)));
		if (p != scTSFCidx[i])
			scTSFCidx[i] = p, redraw = true;
	}
	if (redraw) {
		oapiBltPanelAreaBackground (AID_SCRAMDISP3, surf);
		return RedrawPanel_IndicatorPair (surf, scTSFCidx, 66);
	} else return false;
}

bool DeltaGlider::RedrawPanel_ScramFlow (SURFHANDLE surf)
{
	bool redraw = false;
	for (int i = 0; i < 2; i++) {
		int p = min (66, (int)(scramjet->DMF(i)/3.0*67.0));
		if (p != scflowidx[i])
			scflowidx[i] = p, redraw = true;
	}
	if (redraw) {
		oapiBltPanelAreaBackground (AID_SCRAMDISP2, surf);
		return RedrawPanel_IndicatorPair (surf, scflowidx, 66);
	} else return false;
}


bool DeltaGlider::RedrawPanel_MainPropMass (SURFHANDLE surf)
{
	int m = (int)(GetPropellantMass (ph_main)+0.5);
	if (m != mainpropmass) {
		char cbuf[8];
		mainpropmass = m;
		sprintf (cbuf, "%05d", m); //"%05d"
		return  RedrawPanel_Number (surf, 0, 0, cbuf); //RedrawPanel_Number
	} else return false;
}



bool DeltaGlider::RedrawPanel_JetPropMass (SURFHANDLE surf)
{
	int m = (int)(GetPropellantMass (ph_jet)+0.5);
	if (m != jetpropmass) {
		char cbuf[8];
		jetpropmass = m;
		sprintf (cbuf, "%05d", m);
		return RedrawPanel_Number (surf, 0, 0, cbuf);
	} else return false;
}

bool DeltaGlider::RedrawPanel_RCSPropMass (SURFHANDLE surf)
{
	int m = (int)(GetPropellantMass (ph_rcs)+0.5);
	if (m != rcspropmass) {
		char cbuf[8];
		rcspropmass = m;
		sprintf (cbuf, "%05d", m);
		return RedrawPanel_Number (surf, 0, 0, cbuf);
	} else return false;
}

bool DeltaGlider::RedrawPanel_ScramPropMass (SURFHANDLE surf)
{
	int m = (int)(GetPropellantMass (ph_scram)+0.5);
	if (m != scrampropmass) {
		char cbuf[8];
		scrampropmass = m;
		sprintf (cbuf, "%05d", m);
		return RedrawPanel_Number (surf, 0, 0, cbuf);
	} else return false;
}

bool DeltaGlider::RedrawPanel_battery_charge_001 (SURFHANDLE surf)
{
	
	int m = battery_charge_001;
	if (m != batpropmass) {
		char cbuf[8];
		batpropmass = m;
		sprintf (cbuf, "%05d", m);
		return RedrawPanel_Number (surf, 0, 0, cbuf);
	} else return false;
	
}



bool DeltaGlider::RedrawPanel_ElevTrim (SURFHANDLE surf)
{
	double level = GetControlSurfaceLevel (AIRCTRL_ELEVATORTRIM);
	UINT pos = (UINT)((1.0+level)*23.0);
	if (pos != elevtrimpos) {
		int w = (oapiCockpitMode() == COCKPIT_VIRTUAL ? 2:15);
		oapiColourFill (surf, 0);
		oapiColourFill (surf, oapiGetColour (210,210,210), 1, pos, w, 6);
		elevtrimpos = pos;
		return true;
	} else return false;
}

bool DeltaGlider::RedrawPanel_RotVelocity (SURFHANDLE surf, int which)
{
	int idx;
	double v, av;
	VECTOR3 vrot;
	GetAngularVel (vrot);
	v  = (which == AID_VPITCH ? -vrot.x : which == AID_VBANK ? -vrot.z : vrot.y);
	av = fabs(v*DEG);

	if      (av <  1.0) idx = 0;
	else if (av < 11.0) idx = 1 + (int)((av-1.0)*0.4);
	else if (av < 45.0) idx = 5 + (int)((av-11.0)*3.0/34.0);
	else                idx = 8;
	if (v >= 0.0) idx  = 8-idx;
	else          idx += 8;

	if (idx == rotidx[0][which-AID_VPITCH]) return false;
	rotidx[0][which-AID_VPITCH] = idx;
	switch (which) {
		case AID_VPITCH: oapiBlt (surf, srf[4], 0, 0, idx*40, 0, 40, 49); break;
		case AID_VBANK:  oapiBlt (surf, srf[5], 0, 0, idx*50, 0, 50, 40); break;
		case AID_VYAW:   oapiBlt (surf, srf[6], 0, 0, idx*50, 0, 50, 40); break;
	}
	return true;
}

bool DeltaGlider::RedrawPanel_RotAcceleration (SURFHANDLE surf, int which)
{
	int idx;
	double a, aa;
	VECTOR3 arot;
	GetAngularAcc (arot);
	a  = (which == AID_APITCH ? -arot.x : which == AID_ABANK ? -arot.z : arot.y);
	a *= 2.0;
	aa = fabs(a*DEG);

	if      (aa <  1.0) idx = 0;
	else if (aa < 11.0) idx = 1 + (int)((aa-1.0)*0.4);
	else if (aa < 45.0) idx = 5 + (int)((aa-11.0)*3.0/34.0);
	else                idx = 8;
	if (a >= 0.0) idx  = 8-idx;
	else          idx += 8;

	if (idx == rotidx[1][which-AID_VPITCH]) return false;
	rotidx[1][which-AID_VPITCH] = idx;
	switch (which) {
		case AID_APITCH: oapiBlt (surf, srf[4], 0, 0, idx*40, 0, 40, 49); break;
		case AID_ABANK:  oapiBlt (surf, srf[5], 0, 0, idx*50, 0, 50, 40); break;
		case AID_AYAW:   oapiBlt (surf, srf[6], 0, 0, idx*50, 0, 50, 40); break;
	}
	return true;
}

bool DeltaGlider::RedrawPanel_RotMoment (SURFHANDLE surf, int which)
{
	int idx;
	double m, am;
	VECTOR3 amom;
	GetAngularMoment (amom);
	m  = (which == AID_MPITCH ? -amom.x : which == AID_MBANK ? -amom.z : amom.y);
	m *= 1e-3;
	am = fabs(m);

	if      (am <  1.0) idx = 0;
	else if (am < 11.0) idx = 1 + (int)((am-1.0)*0.4);
	else if (am < 45.0) idx = 5 + (int)((am-11.0)*3.0/34.0);
	else                idx = 8;
	if (m >= 0.0) idx  = 8-idx;
	else          idx += 8;

	if (idx == rotidx[2][which-AID_VPITCH]) return false;
	rotidx[2][which-AID_VPITCH] = idx;
	switch (which) {
		case AID_MPITCH: oapiBlt (surf, srf[4], 0, 0, idx*40, 0, 40, 49); break;
		case AID_MBANK:  oapiBlt (surf, srf[5], 0, 0, idx*50, 0, 50, 40); break;
		case AID_MYAW:   oapiBlt (surf, srf[6], 0, 0, idx*50, 0, 50, 40); break;
	}
	return true;
}

bool DeltaGlider::RedrawPanel_ScramTempDisp (SURFHANDLE surf)
{
	double T, phi;
	static const double rad = 19.0;
	int i, j, x0, y0, dx, dy;
	bool isVC = (oapiCockpitMode() == COCKPIT_VIRTUAL);

	HDC hDC = oapiGetDC (surf);
	SelectObject (hDC, g_Param.pen[0]);
	for (j = 0; j < 3; j++) {
		for (i = 0; i < 2; i++) {
			T = scramjet->Temp (i, j);
			phi = PI * min (T,3900.0)/2000.0;
			dx = (int)(rad*sin(phi)), dy = (int)(rad*cos(phi));
			x0 = (isVC ? 20 : 22-j) + i*43;
			y0 = 19+j*46;
			MoveToEx (hDC, x0, y0, NULL); LineTo (hDC, x0+dx, y0-dy);
		}
	}
	SelectObject (hDC, GetStockObject (BLACK_PEN));
	oapiReleaseDC (surf, hDC);
	return true;
}

bool DeltaGlider::RedrawPanel_WBrake (SURFHANDLE surf, int which)
{
	double level = GetWheelbrakeLevel (which);
	UINT pos = (UINT)(level*93.0);
	if (pos != wbrake_pos[which-1]) {
		oapiBlt (surf, srf[0], 0, pos, (which-1)*34, 0, 34, 86);
		wbrake_pos[which-1] = pos;
		return true;
	}
	return false;
}

void DeltaGlider::RedrawPanel_MFDButton (SURFHANDLE surf, int mfd, int side)
{
	HDC hDC = oapiGetDC (surf);
	HFONT pFont = (HFONT)SelectObject (hDC, g_Param.font[1]);
	SetTextColor (hDC, RGB(196, 196, 196));
	SetTextAlign (hDC, TA_CENTER);
	SetBkMode (hDC, TRANSPARENT);
	const char *label;
	bool isVC = (oapiCockpitMode() == COCKPIT_VIRTUAL);
	int x = (isVC ? 12:13);
	int y = (isVC ? 0:3);

	for (int bt = 0; bt < 6; bt++) {
		if (label = oapiMFDButtonLabel (mfd, bt+side*6)) {
			TextOut (hDC, x, y, label, strlen (label));
			if (isVC) x += 24;
			else      y += 41;
		} else break;
	}

	SelectObject (hDC, pFont);
	oapiReleaseDC (surf, hDC);
}

bool DeltaGlider::RedrawPanel_IndicatorPair (SURFHANDLE surf, int *p, int range)
{
	oapiBlt (surf, srf[8], 0, range-p[0], 0, 0, 6, 7, SURF_PREDEF_CK);
	oapiBlt (surf, srf[8], 7, range-p[1], 6, 0, 6, 7, SURF_PREDEF_CK);
	return true;
}

bool DeltaGlider::RedrawPanel_Number (SURFHANDLE surf, int x, int y, char *num)
{
	for (; *num; num++) {
		oapiBlt (surf, srf[10], x, y, (*num-'0')*7, 0, 6, 9);
		x += 6;
	}
	return true;
}

bool DeltaGlider::RedrawPanel_Number_1 (SURFHANDLE surf, int x, int y, char *num)
{
	for (; *num; num++) {
		oapiBlt (surf, srf[0], x, y, (*num-'0')*7, 0, 6, 9);
		x += 6;
	}
	return true;
}


// D. Beachy: begin refactored section to fix flow rate panels
bool DeltaGlider::RedrawPanel_MainFlow (SURFHANDLE surf)
{
	double gaugeSize = 66.99;  // pointer can move 66 pixels; also round up to next pixel
	bool redraw = false;
	for (int i = 0; i < 2; i++) {
		double flowRate = GetThrusterFlowRate(th_main[i]);
        int p = (int)min(flowRate*gaugeSize/5.1, gaugeSize);  // gauge maxes out at 5.1
		if (p != mainflowidx[i])
			mainflowidx[i] = p, redraw = true;
	}
	if (redraw) {
		oapiBltPanelAreaBackground (AID_MAINDISP1, surf);
		return RedrawPanel_IndicatorPair (surf, mainflowidx, 66);
	} else return false;
}

bool DeltaGlider::RedrawPanel_RetroFlow (SURFHANDLE surf)
{
    double gaugeSize = 66.99;  // pointer can move 66 pixels; also round up to next pixel
	bool redraw = false;
	for (int i = 0; i < 2; i++) {
		double flowRate = GetThrusterFlowRate(th_retro[i]); 
		int p = (int)min(flowRate*gaugeSize/0.9,gaugeSize); // gauge maxes out at 0.9
		if (p != retroflowidx[i])
			retroflowidx[i] = p, redraw = true;
	}
	if (redraw) {
		oapiBltPanelAreaBackground (AID_MAINDISP2, surf);
		return RedrawPanel_IndicatorPair (surf, retroflowidx, 66);
	} else return false;
}

bool DeltaGlider::RedrawPanel_HoverFlow (SURFHANDLE surf)
{
    double gaugeSize = 66.99;  // pointer can move 66 pixels; also round up to next pixel
    // since hover flow rates are always locked we can assume the second hover thruster has the same flow as the first
    double flowRate = GetThrusterFlowRate(th_hover[0]); 
	int p = (int)min(flowRate*gaugeSize/3.6,gaugeSize); // gauge maxes out at 3.6
	if (p != hoverflowidx) {
		hoverflowidx = p;
		oapiBltPanelAreaBackground (AID_MAINDISP3, surf);
		// draw a pair of matching indicators
		oapiBlt (surf, srf[8], 0, 66-hoverflowidx, 0, 0, 6, 7, SURF_PREDEF_CK);
		oapiBlt (surf, srf[8], 7, 66-hoverflowidx, 6, 0, 6, 7, SURF_PREDEF_CK);
		return true;
	} else return false;
}

double DeltaGlider::GetThrusterFlowRate(THRUSTER_HANDLE th)
{
    double level  = GetThrusterLevel(th); // throttle level
    double isp    = GetThrusterIsp0(th);
    double thrust = GetThrusterMax0(th);
    double flow   = thrust*level/isp;
    
    return flow;
}
// D. Beachy: end refactored section

bool DeltaGlider::RedrawPanel_MainTSFC (SURFHANDLE surf)
{
	static const double scalemin = 0.02, scalemax = 0.035; // display range
	double tsfc = 1e3/GetThrusterIsp (th_main[0]);
	// we assume that all DG rocket engines have the same Isp
	int p = max (0, min (66, (int)((tsfc-scalemin)/(scalemax-scalemin)*67.0)));
	if (p != mainTSFCidx) {
		mainTSFCidx = p;
		oapiBltPanelAreaBackground (AID_MAINDISP4, surf);
		oapiBlt (surf, srf[8], 0, 66-mainTSFCidx, 0, 0, 6, 7, SURF_PREDEF_CK);
		return true;
	} else return false;
}

bool DeltaGlider::RedrawPanel_PGimbalMainDisp (SURFHANDLE surf)
{
	oapiBlt (surf, srf[8], 0, mpgimbalidx[0], 0, 0, 6, 7, SURF_PREDEF_CK);
	oapiBlt (surf, srf[8], 7, mpgimbalidx[1], 6, 0, 6, 7, SURF_PREDEF_CK);
	return true;
}

bool DeltaGlider::RedrawPanel_YGimbalMainDisp (SURFHANDLE surf)
{
	oapiBlt (surf, srf[8], mygimbalidx[0], 0, 0, 8, 7, 6, SURF_PREDEF_CK);
	oapiBlt (surf, srf[8], mygimbalidx[1], 7, 7, 8, 7, 6, SURF_PREDEF_CK);
	return true;
}

bool DeltaGlider::RedrawPanel_GimbalScramDisp (SURFHANDLE surf)
{
	oapiBlt (surf, srf[8], 0, scgimbalidx[0], 0, 0, 6, 7, SURF_PREDEF_CK);
	oapiBlt (surf, srf[8], 7, scgimbalidx[1], 6, 0, 6, 7, SURF_PREDEF_CK);
	return true;
}

bool DeltaGlider::RedrawPanel_HoverBalanceDisp (SURFHANDLE surf)
{
	oapiBlt (surf, srf[8], 0, hbalanceidx, 0, 0, 6, 7, SURF_PREDEF_CK);
	return true;
}

bool DeltaGlider::RedrawPanel_GearIndicator (SURFHANDLE surf)
{
	switch (gear_status) {
	case DOOR_CLOSED: oapiBlt (surf, srf[9], 0,  0, 0,  0, 29, 5); break;
	case DOOR_OPEN:   oapiBlt (surf, srf[9], 0, 26, 0,  5, 29, 5); break;
	default:          oapiBlt (surf, srf[9], 0, 13, 0, 20, 29, 5); break;
	}
	return true;
}

bool DeltaGlider::RedrawPanel_NoseconeIndicator (SURFHANDLE surf)
{
	switch (NOSE_CONE_STATUS) {
	case DOOR_CLOSED: oapiBlt (surf, srf[9], 0,  0, 0, 10, 29, 5); break;
	case DOOR_OPEN:   oapiBlt (surf, srf[9], 0, 26, 0, 15, 29, 5); break;
	default:          oapiBlt (surf, srf[9], 0, 13, 0, 20, 29, 5); break;
	}
	return true;
}



void DeltaGlider::SetPassengerVisuals ()
{/*
	if (!(vcmesh && exmesh)) return;

	static int expsngridx[4] = {106, 107, 108, 109};
	static int exvisoridx[4] = {111, 112, 113, 114};
	static int vcpsngridx[4] = {123, 124, 125, 126};
	static int vcvisoridx[4] = {130, 131, 132, 133};

	for (DWORD i = 0; i < 4; i++) {
		if (psngr[i]) {
			oapiMeshGroup (exmesh, expsngridx[i])->UsrFlag = 1;
			oapiMeshGroup (exmesh, exvisoridx[i])->UsrFlag = 1;
			oapiMeshGroup (vcmesh, vcpsngridx[i])->UsrFlag = 1;
			oapiMeshGroup (vcmesh, vcvisoridx[i])->UsrFlag = 1;
		} else {
			oapiMeshGroup (exmesh, expsngridx[i])->UsrFlag |= 3;
			oapiMeshGroup (exmesh, exvisoridx[i])->UsrFlag |= 3;
			oapiMeshGroup (vcmesh, vcpsngridx[i])->UsrFlag |= 3;
			oapiMeshGroup (vcmesh, vcvisoridx[i])->UsrFlag |= 3;
		}
	}*/
}


/*
void DeltaGlider::SetDamageVisuals ()
{
	if (!exmesh) return;

	int i, j;

	// ailerons
	static UINT LAileronGrp[4] = {29,51,30,52};
	for (i = 0; i < 4; i++) {
		for (j = 0; j < 2; j++)
			if (aileronfail[i])
				oapiMeshGroup (exmesh, AileronGrp[i*2+j])->UsrFlag |= 3;
			else
				oapiMeshGroup (exmesh, AileronGrp[i*2+j])->UsrFlag = 0;
	}

	// top hatch
	for (i = 0; i < 2; i++)
		oapiMeshGroup (exmesh, HatchGrp[i])->UsrFlag = (hatchfail < 2 ? 0:3);
	if (hatchfail == 1)
		SetAnimation (anim_hatch, hatch_proc = 0.2);
}
*/
void DeltaGlider::DrawNeedle (HDC hDC, int x, int y, double rad, double angle, double *pangle, double vdial)
{
	if (pangle) { // needle response delay
		double dt = oapiGetSimStep();
		if (fabs (angle - *pangle)/dt >= vdial)
			angle = (angle > *pangle ? *pangle+vdial*dt : *pangle-vdial*dt);
		*pangle = angle;
	}
	double dx = rad * cos(angle), dy = rad * sin(angle);
	SelectObject (hDC, g_Param.pen[1]);
	MoveToEx (hDC, x, y, 0); LineTo (hDC, x + (int)(0.85*dx+0.5), y - (int)(0.85*dy+0.5));
	SelectObject (hDC, g_Param.pen[0]);
	MoveToEx (hDC, x, y, 0); LineTo (hDC, x + (int)(dx+0.5), y - (int)(dy+0.5));
}







static float tv0[8] = {0,0,0.0469f,0.0469f,0,0,0.0469f,0.0469f};

// ======
// Overloaded callback functions
// ======

// --------------------------------------------------------------
// Set vessel class parameters
// --------------------------------------------------------------
void DeltaGlider::clbkSetClassCaps (FILEHANDLE cfg)
{
	// *************** physical parameters **********************

	//bool b;
	//if (oapiReadItem_bool (cfg, "SCRAMJET", b) && b) // set up scramjet configuration
		scramjet = new Ramjet (this);

	VESSEL2::SetEmptyMass (scramjet ? EMPTY_MASS_SC : EMPTY_MASS);
	VECTOR3 r[2] = {{0,0,6}, {0,0,-4}};
	SetSize (10.0);
	SetVisibilityLimit (7.5e-4, 1.5e-3);
	SetAlbedoRGB (_V(0.77,0.20,0.13));
	SetGravityGradientDamping (20.0);
	SetCW (0.09, 0.09, 2, 1.4);
	SetWingAspect (0.7);
	SetWingEffectiveness (2.5);
	SetCrossSections (_V(114.05,400.82,35.96)); //(_V(53.0,186.9,25.9));
	SetSurfaceFrictionCoeff (0.07, 0.3);
	SetMaxWheelbrakeForce (2e5);
	SetPMI (_V(15.5,22.1,7.7));

	SetDockParams (_V(0, -0.820846, 16.794108), _V(0,0,1), _V(0,1,0));
	SetTouchdownPoints (_V(0, -5.188098, 12.113704), _V(-5.737381, -5.177002, -6.266663), _V(5.737381, -5.177002, -6.266663));
	EnableTransponder (true);
	bool render_cockpit = false;
    char attach_id[8];//={"AT"};
	
	payload_attachment[0]  = CreateAttachment (false,_V(1.76f,0.0f, 5.821f),_V(0.0f,0.0f,-1.0f),_V(0.0f,1.0f,0.0f),attach_id);






	// ******************** NAV radios **************************

	InitNavRadios (4);

	// ****************** propellant specs **********************

	tankconfig = 0; // provide rocket fuel only by default
	max_scramfuel = 1000.0;
	max_rocketfuel = TANK1_CAPACITY + TANK2_CAPACITY;
    max_jetfule = 5000.0;
	max_battery = 100;
	
	ph_main  = CreatePropellantResource (max_rocketfuel);    // main tank (fuel + oxydant)
	ph_rcs   = CreatePropellantResource (RCS_FUEL_CAPACITY); // RCS tank  (fuel + oxydant)
	ph_jet = CreatePropellantResource (max_jetfule);
	//ph_battery = CreatePropellantResource (max_battery);
	ph_scram = CreatePropellantResource (max_scramfuel); // scramjet fuel

	// **************** thruster definitions ********************

	double ispscale = (modelidx ? 0.8 : 1.0);
	// Reduction of thrust efficiency at normal pressure

	

	
	PARTICLESTREAMSPEC contrail = {
		0, 8.0, 3, 150, 0.3, 3.5, 4, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
		PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
	};
	PARTICLESTREAMSPEC exhaust_main = {
		0, 2.0, 10, 150, 0.1, 0.2, 16, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
		PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
	};
	PARTICLESTREAMSPEC exhaust_hover = {
		0, 1.5, 20, 150, 0.1, 0.15, 9, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
		PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
	};
	PARTICLESTREAMSPEC exhaust_scram = {
		0, 2.0, 10, 150, 0.1, 0.2, 16, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
		PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
	};

	// main thrusters
	th_main[0] = CreateThruster (_V(-1,0.0,-7.7), _V(0,0,1), MAX_MAIN_THRUST[modelidx], ph_main, ISP, ISP*ispscale);
	th_main[1] = CreateThruster (_V( 1,0.0,-7.7), _V(0,0,1), MAX_MAIN_THRUST[modelidx], ph_main, ISP, ISP*ispscale);
	thg_main = CreateThrusterGroup (th_main, 2, THGROUP_MAIN);
	AddExhaust (th_main[0], 12, 1);
	AddExhaust (th_main[1], 12, 1);
	AddExhaustStream (th_main[0], _V(-1,0,-15), &contrail);
	AddExhaustStream (th_main[1], _V( 1,0,-15), &contrail);
	AddExhaustStream (th_main[0], _V(-1,0,-10), &exhaust_main);
	AddExhaustStream (th_main[1], _V( 1,0,-10), &exhaust_main);
	//DWORD i = GetGroupThrusterCount (THGROUP_MAIN);
	
	
	//revertEngine(2);
	//setScram();
	
	
	RCS_MODE ();
	

	// retro thrusters
	// note that we have to tilt retros slightly downwards to avoid inducing
	// an angular momentum, since they are mounted below the level of CG.
	// This also means that retros will induce an upward linear component.
	th_retro[0] = CreateThruster (_V(-3,-0.236,5.6), _V(0,0.04210548,-0.99911317), MAX_RETRO_THRUST, ph_main, ISP, ISP*ispscale);
	th_retro[1] = CreateThruster (_V( 3,-0.236,5.6), _V(0,0.04210548,-0.99911317), MAX_RETRO_THRUST, ph_main, ISP, ISP*ispscale);
	thg_retro = CreateThrusterGroup (th_retro, 2, THGROUP_RETRO);
	AddExhaust (th_retro[0], 3, 0.4);
	AddExhaust (th_retro[1], 3, 0.4);

	// hover thrusters (simplified)
	// The two aft hover engines are combined into a single "logical" thrusters,
	// but exhaust is rendered separately for both
	th_hover[0] = CreateThruster (_V(0,0,3), _V(0,1,0), MAX_HOVER_THRUST[modelidx], ph_main, ISP, ISP*ispscale);
	th_hover[1] = CreateThruster (_V(0,0,-3), _V(0,1,0), MAX_HOVER_THRUST[modelidx], ph_main, ISP, ISP*ispscale);
	thg_hover = CreateThrusterGroup (th_hover, 2, THGROUP_HOVER);
	AddExhaust (th_hover[0], 6, 0.5, _V( 0,-1.6, 3), _V(0,-1,0));
	AddExhaust (th_hover[1], 6, 0.5, _V(-3,-1.3,-4.55), _V(0,-1,0));
	AddExhaust (th_hover[1], 6, 0.5, _V( 3,-1.3,-4.55), _V(0,-1,0));
	AddExhaustStream (th_hover[0], _V(0,-4,0), &contrail);
	AddExhaustStream (th_hover[0], _V(0,-2,3), &exhaust_hover);
	AddExhaustStream (th_hover[0], _V(-3,-2,-4.55), &exhaust_hover);
	AddExhaustStream (th_hover[0], _V( 3,-2,-4.55), &exhaust_hover);


	// ********************* aerodynamics ***********************

	hwing = CreateAirfoil3 (LIFT_VERTICAL, _V(0,0,-0.3), VLiftCoeff, 0, 5, 90, 1.5);
	// wing and body lift+drag components

	CreateAirfoil3 (LIFT_HORIZONTAL, _V(0,0,-4), HLiftCoeff, 0, 5, 15, 1.5);
	// vertical stabiliser and body lift and drag components

	CreateControlSurface (AIRCTRL_ELEVATOR,     1.4, 1.5, _V(   0,0,-7.2), AIRCTRL_AXIS_XPOS, anim_elevator);
	CreateControlSurface (AIRCTRL_RUDDER,       0.8, 1.5, _V(   0,0,-7.2), AIRCTRL_AXIS_YPOS, anim_rudder);
	hlaileron = CreateControlSurface2 (AIRCTRL_AILERON, 0.3, 1.5, _V( 7.5,0,-7.2), AIRCTRL_AXIS_XPOS, anim_raileron);
	hraileron = CreateControlSurface2 (AIRCTRL_AILERON, 0.3, 1.5, _V(-7.5,0,-7.2), AIRCTRL_AXIS_XNEG, anim_laileron);
	CreateControlSurface (AIRCTRL_ELEVATORTRIM, 0.3, 1.5, _V(   0,0,-7.2), AIRCTRL_AXIS_XPOS, anim_elevatortrim);

	CreateVariableDragElement (&gear_proc, 0.8, _V(0, -1, 0));     // landing gear
	CreateVariableDragElement (&rcover_proc, 0.2, _V(0,-0.5,6.5)); // retro covers
	CreateVariableDragElement (&nose_cone_proc, 3, _V(0, 0, 8));        // nose cone
	CreateVariableDragElement (&radiator_proc, 1, _V(0,1.5,-4));   // radiator
	CreateVariableDragElement (&brake_proc, 4, _V(0,0,-8));        // airbrake

	SetRotDrag (_V(0.10,0.13,0.04));
	// angular damping

	// ************************* mesh ***************************

	// ********************* beacon lights **********************
	static VECTOR3 beaconpos[8] = {{-8.6,0,-3.3}, {8.6,0,-3.3}, {0,0.5,-7.5}, {0,2.2,2}, {0,-1.4,2}, {-8.9,2.5,-5.4}, {8.9,2.5,-5.4}, {0,-1.8,2}};
	static VECTOR3 beaconcol[7] = {{1.0,0.5,0.5}, {0.5,1.0,0.5}, {1,1,1}, {1,0.6,0.6}, {1,0.6,0.6}, {1,1,1}, {1,1,1}};
	
	int i;
	for (i = 0; i < 7; i++) {
		beacon[i].shape = (i < 3 ? BEACONSHAPE_DIFFUSE : BEACONSHAPE_STAR);
		beacon[i].pos = beaconpos+i;
		beacon[i].col = beaconcol+i;
		beacon[i].size = (i < 3 ? 0.3 : 0.55);
		beacon[i].falloff = (i < 3 ? 0.4 : 0.6);
		beacon[i].period = (i < 3 ? 0 : i < 5 ? 2 : 1.13);
		beacon[i].duration = (i < 5 ? 0.1 : 0.05);
		beacon[i].tofs = (6-i)*0.2;
		beacon[i].active = false;
		AddBeacon (beacon+i);
	}
	
	
		beacon[4].pos = beaconpos+7;

	
	SetMeshVisibilityMode (AddMesh (exmesh_tpl = oapiLoadMeshGlobal ("at1000\\at1000")), MESHVIS_EXTERNAL);
	
	
// Ummu call of our own function to keep listing clear.
	
	clbkSetClassCaps_UMMu();


}



// --------------------------------------------------------------
// Finalise vessel creation
// --------------------------------------------------------------
void DeltaGlider::clbkPostCreation ()
{
	
	
	SetGearParameters (gear_proc);
	SetEmptyMass ();
    DefineSound ();
	//revertEngine2 (2);
	
	
	

	// update animation states
	SetAnimation (anim_gear, gear_proc);
	SetAnimation (anim_air_lock_tube, air_lock_tube_proc);
	SetAnimation (anim_rcover, rcover_proc);
	SetAnimation (anim_nose, nose_cone_proc);
	SetAnimation (anim_ladder, ladder_proc);
	SetAnimation (anim_olock, outer_air_lock_proc);
	SetAnimation (anim_ilock, inner_air_lock_proc);
	SetAnimation (anim_hatch, hatch_proc);
	SetAnimation (anim_radiator, radiator_proc);
	SetAnimation (anim_brake, brake_proc);
	SetAnimation (anim_reverser, reverser_proc);



	/*
	VECTOR3 pos = _V(0, -0.936493, 15.257813);         // check line 1633  SetDockParams  if I coment it out the ship locks up when I dock               
	VECTOR3 dir = _V(0,0,1);                               
	VECTOR3 rot = _V(0,0,1);
	MainDockHandle = CreateDock(pos,dir,rot);
	*/

	
}

// --------------------------------------------------------------
// Respond to playback event
// --------------------------------------------------------------
bool DeltaGlider::clbkPlaybackEvent (double simt, double event_t, const char *event_type, const char *event)
{
	if (!stricmp (event_type, "GEAR")) {
		ActivateLandingGear (!stricmp (event, "UP") ? DOOR_CLOSING : DOOR_OPENING);
		return true;
	} else if (!stricmp (event_type, "NOSECONE")) {
		ActivateNoseCone (!stricmp (event, "CLOSE") ? DOOR_CLOSING : DOOR_OPENING);
		return true;
	} 
 else if (!stricmp (event_type, "RADIATOR")) {
		ActivateRadiator (!stricmp (event, "CLOSE") ? DOOR_CLOSING : DOOR_OPENING);
		return true;
	} else if (!stricmp (event_type, "AIRBRAKE")) {
		ActivateAirbrake(!stricmp (event, "CLOSE") ? DOOR_CLOSING : DOOR_OPENING);
		return true;
	} else if (!stricmp (event_type, "HATCH")) {
		ActivateHatch (!stricmp (event, "CLOSE") ? DOOR_CLOSING : DOOR_OPENING);
		return true;
	} else if (!stricmp (event_type, "OLOCK")) {
		ActivateOuterAirlock (!stricmp (event, "CLOSE") ? DOOR_CLOSING : DOOR_OPENING);
		return true;
	} else if (!stricmp (event_type, "ILOCK")) {
		ActivateInnerAirlock (!stricmp (event, "CLOSE") ? DOOR_CLOSING : DOOR_OPENING);
		return true;
	} else if (!stricmp (event_type, "LADDER")) {
		ActivateLadder (!stricmp (event, "CLOSE") ? DOOR_CLOSING : DOOR_OPENING);
		return true;
	}
	return false;
}

// --------------------------------------------------------------
// Create DG visual
// --------------------------------------------------------------
void DeltaGlider::clbkVisualCreated (VISHANDLE vis, int refcount)
{
	visual = vis;
	exmesh = GetMesh (vis, 0);
	//UpdateStatusIndicators();
	
}

// --------------------------------------------------------------
// Destroy DG visual
// --------------------------------------------------------------
void DeltaGlider::clbkVisualDestroyed (VISHANDLE vis, int refcount)
{
	visual = NULL;
	exmesh = NULL;
	
}

// --------------------------------------------------------------
// Respond to MFD mode change
// --------------------------------------------------------------
void DeltaGlider::clbkMFDMode (int mfd, int mode)
{
	switch (mfd) {
	case MFD_LEFT:
		oapiTriggerRedrawArea (0, 0, AID_MFD1_LBUTTONS);
		oapiTriggerRedrawArea (0, 0, AID_MFD1_RBUTTONS);
		break;
	case MFD_RIGHT:
		oapiTriggerRedrawArea (0, 0, AID_MFD2_LBUTTONS);
		oapiTriggerRedrawArea (0, 0, AID_MFD2_RBUTTONS);
		break;
	}
}

// --------------------------------------------------------------
// Respond to RCS mode change
// --------------------------------------------------------------
void DeltaGlider::clbkRCSMode (int mode)
{
	oapiTriggerRedrawArea (0, 0, AID_ATTITUDEMODE);
}

// --------------------------------------------------------------
// Respond to control surface mode change
// --------------------------------------------------------------
void DeltaGlider::clbkADCtrlMode (DWORD mode)
{
	oapiTriggerRedrawArea (0, 0, AID_ADCTRLMODE);
}

// --------------------------------------------------------------
// Respond to HUD mode change
// --------------------------------------------------------------
void DeltaGlider::clbkHUDMode (int mode)
{
	oapiTriggerRedrawArea (0, 0, AID_HUDMODE);
}

// --------------------------------------------------------------
// Respond to navmode change
// --------------------------------------------------------------
void DeltaGlider::clbkNavMode (int mode, bool active)
{
	oapiTriggerRedrawArea (0, 0, AID_NAVMODE);
}


bool DeltaGlider::clbkLoadGenericCockpit ()
{
	SetCameraOffset (_V(0,1.467,6.782));
	oapiSetDefNavDisplay (1);
	oapiSetDefRCSDisplay (1);
	campos = CAM_GENERIC;
	return true;
}

// --------------------------------------------------------------
// Load 2-D instrument panel mode
// --------------------------------------------------------------
bool DeltaGlider::clbkLoadPanel (int id)
{
	
	int xofs;
	ReleaseSurfaces();

	HBITMAP hBmp = LoadBitmap (g_Param.hDLL, MAKEINTRESOURCE (IDB_PANEL1+id));
	MFDSPEC mfds_left  = {{227, 61, 517, 351}, 6, 6, 47, 41};
	MFDSPEC mfds_right = {{636, 61, 926, 351}, 6, 6, 47, 41};

	SetCameraOffset (_V(0,1.467,6.782));

	switch (id) {
	case 0: // main panel
		
		
		oapiRegisterPanelBackground (hBmp, PANEL_ATTACH_BOTTOM|PANEL_MOVEOUT_BOTTOM, 0xffffff);
		oapiSetPanelNeighbours (3,-1,1,2);
		SetCameraDefaultDirection (_V(0,0,1)); // look forward
		// panel id
		oapiRegisterPanelArea (AID_HUD_PANEL_ID0,        _R(1,  1, 2, 2), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		
		oapiRegisterMFD (MFD_LEFT,  mfds_left);
		oapiRegisterMFD (MFD_RIGHT, mfds_right);
		oapiRegisterPanelArea (AID_ATTITUDEMODE,        _R(1089,  69, 1129, 113), PANEL_REDRAW_MOUSE, PANEL_MOUSE_DOWN);
		oapiRegisterPanelArea (AID_ADCTRLMODE,          _R(1005,  69, 1045, 113), PANEL_REDRAW_MOUSE, PANEL_MOUSE_DOWN);
		oapiRegisterPanelArea (AID_NAVMODE,             _R( 990, 119, 1144, 195), PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN, PANEL_MAP_BACKGROUND);
		oapiRegisterPanelArea (AID_HUDMODE,             _R(  15,  18,  122,  33), PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN|PANEL_MOUSE_ONREPLAY, PANEL_MAP_BACKGROUND);
		oapiRegisterPanelArea (AID_MAINDISP1,           _R( 236, 413,  249, 486), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BGONREQUEST);
		oapiRegisterPanelArea (AID_MAINDISP2,           _R( 271, 413,  284, 486), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BGONREQUEST);
        
		oapiRegisterPanelArea (AID_MAINDISP3,           _R( 306, 413,  319, 486), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BGONREQUEST);
		oapiRegisterPanelArea (AID_MAINDISP4,           _R( 209, 413,  215, 486), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BGONREQUEST);
		
		oapiRegisterPanelArea (AID_MWS,                 _R( 943,   5,  972,  34), PANEL_REDRAW_USER | PANEL_REDRAW_MOUSE, PANEL_MOUSE_LBDOWN);// this is warn light
		oapiRegisterPanelArea (AID_MAINPROP,            _R(1016, 382, 1029, 477), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BGONREQUEST);
		
		oapiRegisterPanelArea (AID_BATTERYCHARGE,       _R(1050, 439, 1080, 448), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_JETPROPMASS,         _R(1050, 453, 1080, 462), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_MAINPROPMASS,        _R(1050, 466, 1080, 475), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_RCSPROPMASS,         _R(1050, 480, 1080, 489), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
        oapiRegisterPanelArea (AID_RCSPROP,             _R(1056, 382, 1069, 477), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BGONREQUEST);
		
		//oapiRegisterPanelArea (AID_Cargo_Name,           _R(760, 410, 960, 435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND);
        //oapiRegisterPanelArea (AID_Cargo_Selector,       _R(739, 405, 747, 434), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);

		oapiRegisterPanelArea (AID_Crew_Member_Name,     _R(510, 412, 700, 437), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND);
        oapiRegisterPanelArea (AID_EVA_Selector,         _R(492, 405, 504, 434), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
        oapiRegisterPanelArea (AID_Enter_Airlock,        _R(495, 440, 720, 455), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN,PANEL_MAP_BACKGROUND);
		//oapiRegisterPanelArea (AID_Redraw_Eva_Deploy,    _R(492, 405, 504, 434), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);

		xofs = 182; // left MFD
		oapiRegisterPanelArea (AID_MFD1_BBUTTONS,       _R( 55+xofs,359,325+xofs, 377), PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN|PANEL_MOUSE_ONREPLAY); // bottom button row
		oapiRegisterPanelArea (AID_MFD1_LBUTTONS,       _R(    xofs,100, 25+xofs, 323), PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN|PANEL_MOUSE_LBPRESSED|PANEL_MOUSE_ONREPLAY, PANEL_MAP_BACKGROUND); // left button column
		oapiRegisterPanelArea (AID_MFD1_RBUTTONS,       _R(353+xofs,100,378+xofs, 323), PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN|PANEL_MOUSE_LBPRESSED|PANEL_MOUSE_ONREPLAY, PANEL_MAP_BACKGROUND); // right button column

		xofs = 591; // right MFD
		oapiRegisterPanelArea (AID_MFD2_BBUTTONS,       _R( 55+xofs,359,325+xofs, 377), PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN|PANEL_MOUSE_ONREPLAY); // bottom button row
		oapiRegisterPanelArea (AID_MFD2_LBUTTONS,       _R(    xofs,100, 25+xofs, 323), PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN|PANEL_MOUSE_LBPRESSED|PANEL_MOUSE_ONREPLAY, PANEL_MAP_BACKGROUND); // left button column
		oapiRegisterPanelArea (AID_MFD2_RBUTTONS,       _R(353+xofs,100,378+xofs, 323), PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN|PANEL_MOUSE_LBPRESSED|PANEL_MOUSE_ONREPLAY, PANEL_MAP_BACKGROUND); // right button column

       //Environmental Life Support System
        oapiRegisterPanelArea (AID_Environmental_Control,       _R(997, 348, 1137, 427), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN, PANEL_MAP_BACKGROUND);
       // oapiRegisterPanelArea (AID_CabinTemperature,         _R(1095, 385, 1115, 400), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND);
       // oapiRegisterPanelArea (AID_CabinTemperatureSet,      _R(1124, 385, 1140, 400), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND);






		campos = CAM_PANELMAIN;
		break;

	case 1: // overhead panel  bitmapname panel2
		oapiRegisterPanelBackground (hBmp, PANEL_ATTACH_TOP|PANEL_MOVEOUT_TOP, 0xffffff);
		oapiSetPanelNeighbours (-1,-1,4,0);
		SetCameraDefaultDirection (_V(0,0.5,0.866)); // look up
		// panel id		
		oapiRegisterPanelArea (AID_HUD_PANEL_ID1,        _R(1,  1, 2, 2), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		
		// turbine left
		oapiRegisterPanelArea (AID_TURBINE_FUEL_LEFT,        _R(  98,   73, 126,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_TURBINE_IGNITION_LEFT,    _R( 142,   73, 170,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_TURBINE_START_LEFT,       _R( 180,   103, 208,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		// turbine right
		oapiRegisterPanelArea (AID_TURBINE_FUEL_RIGHT,       _R( 292,   73, 320,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_TURBINE_IGNITION_RIGHT,   _R( 335,   73, 363,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_TURBINE_START_RIGHT,      _R( 373,   103, 401,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		
        oapiRegisterPanelArea (AID_TURBINE_REVERSER,         _R( 454,   73, 482,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
        oapiRegisterPanelArea (AID_PARKING_BRAKE,            _R( 454,  213, 482,  291), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
        oapiRegisterPanelArea (AID_GEARSWITCH,               _R( 454,  350, 482,  428), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		
		
		// scram left
		oapiRegisterPanelArea (AID_SCRAM_FUEL_LEFT,        _R(  98,   213, 126,  291), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_SCRAM_IGNITION_LEFT,    _R( 142,   213, 170,  291), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_SCRAM_START_LEFT,       _R( 180,   243, 208,  291), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		// scram right
		oapiRegisterPanelArea (AID_SCRAM_FUEL_RIGHT,       _R( 292,   213, 320,  291), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_SCRAM_IGNITION_RIGHT,   _R( 335,   213, 363,  291), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_SCRAM_START_RIGHT,      _R( 373,   243, 401,  291), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		
		// ROCKET left
		oapiRegisterPanelArea (AID_ROCKET_FUEL_LEFT,        _R(  98,   357, 126,  435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_ROCKET_IGNITION_LEFT,    _R( 142,   357, 170,  435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		
		// rocket right
		oapiRegisterPanelArea (AID_ROCKET_FUEL_RIGHT,       _R( 292,   357, 320,  435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_ROCKET_IGNITION_RIGHT,   _R( 335,   357, 363,  435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		
		// air lock 
		oapiRegisterPanelArea (AID_NOSECONE,                _R( 615,    73, 643,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_EXTEND_AIRLOCK,          _R( 665,    73, 693,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_CHAMBER,                 _R( 715,    73, 743,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_INNER_AIRLOCK_DOOR,      _R( 765,    73, 793,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_OUTER_AIRLOCK_DOOR,      _R( 815,    73, 843,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_DOCK_RELEASE,            _R( 865,    73, 893,  151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		
        //LIGHTS
          oapiRegisterPanelArea (AID_BEACON_SWITCH,          _R( 934,    73, 962, 151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		  oapiRegisterPanelArea (AID_NAVIGATION_SWITCH,      _R( 984,    73, 1012, 151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		  oapiRegisterPanelArea (AID_STROBE_SWITCH,          _R( 1034,    73, 1062, 151), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		
		// payload bay doors 
          oapiRegisterPanelArea (AID_BAY_DOOR_FORWARD_RIGHT,  _R( 615,   357, 643,  435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
          oapiRegisterPanelArea (AID_BAY_DOOR_AFT_RIGHT,      _R( 665,   357, 693,  435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
          oapiRegisterPanelArea (AID_BAY_DOOR_FORWARD_LEFT,   _R( 715,   357, 743,  435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
          oapiRegisterPanelArea (AID_BAY_DOOR_AFT_LEFT,       _R( 765,   357, 793,  435), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);


		
		/*
		oapiRegisterPanelArea (AID_OUTERAIRLOCKBUTTON,  _R( 240,  30, 265,  68), PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_INNERAIRLOCKBUTTON,  _R( 301,  30, 326,  68), PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN);
		
		
		oapiRegisterPanelArea (AID_VPITCH,              _R( 625,  22, 665,  71), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_VBANK,               _R( 557,  22, 607,  62), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_VYAW,                _R( 491,  22, 541,  62), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_APITCH,              _R( 625,  95, 665, 144), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_ABANK,               _R( 557,  95, 607, 135), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_AYAW,                _R( 491,  95, 541, 135), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_MPITCH,              _R( 625, 168, 665, 217), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE); 
		oapiRegisterPanelArea (AID_MBANK,               _R( 557, 168, 607, 208), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		oapiRegisterPanelArea (AID_MYAW,                _R( 491, 168, 541, 208), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
        
		
		
		
		*/
		
		//	oapiRegisterPanelArea (AID_SCRAMTEMPDISP,   _R( 694,  23, 777, 153), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND);
		
		campos = CAM_PANELUP;
		break;

	case 2: // bottom panel
		oapiRegisterPanelBackground (hBmp, PANEL_ATTACH_TOP|PANEL_ATTACH_BOTTOM, 0xffffff);
		oapiSetPanelNeighbours (-1,-1,0,-1);
		SetCameraDefaultDirection (_V(0,-0.707,0.707)); // look down
		// panel id		
		oapiRegisterPanelArea (AID_HUD_PANEL_ID2,        _R(1,  1, 2, 2), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
		
		
		
		campos = CAM_PANELDN;
		break;
	
	case 3: // EVA panel this will be by the airlock
	oapiRegisterPanelBackground (hBmp, PANEL_ATTACH_TOP|PANEL_ATTACH_BOTTOM, 0xffffff);
	oapiSetPanelNeighbours (-1,0,-1,-1);
	SetCameraDefaultDirection (_V(0,0,1)); // look forward
   campos = CAM_EVA;
	
   // panel id		
		oapiRegisterPanelArea (AID_HUD_PANEL_ID3,        _R(1,  1, 2, 2), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);

	campos = CAM_EVA;
		break;
	


case 4: // power panel
	oapiRegisterPanelBackground (hBmp, PANEL_ATTACH_TOP|PANEL_ATTACH_BOTTOM, 0xffffff);
	oapiSetPanelNeighbours (-1,-1,-1,1);
	SetCameraDefaultDirection (_V(0,0,1)); // look forward

 // panel id		
		oapiRegisterPanelArea (AID_HUD_PANEL_ID4,        _R(1,  1, 2, 2), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_IGNORE);
        oapiRegisterPanelArea (AID_MASTER_POWER,                    _R(70,  70, 98, 148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
        //bay doors
		oapiRegisterPanelArea (AID_MASTER_BAY_DOORS_POWER,          _R(160,  70, 188, 148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
        oapiRegisterPanelArea (AID_BAY_DOOR_FORWARD_RIGHT_POWER,    _R(210,  70, 238, 148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_BAY_DOOR_AFT_RIGHT_POWER,        _R(260,  70, 288, 148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_BAY_DOOR_FORWARD_LEFT_POWER,     _R(310,  70, 338, 148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_BAY_DOOR_AFT_LEFT_POWER,         _R(360,  70, 388, 148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
        // air lock system
		oapiRegisterPanelArea (AID_AIR_LOCK_SYSTEM_POWER,         _R( 420,    70, 448,  148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_NOSECONE_POWER,                _R( 470,    70, 498,  148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_EXTEND_AIRLOCK_POWER,          _R( 520,    70, 548,  148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_CHAMBER_POWER,                 _R( 570,    70, 598,  148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_INNER_AIRLOCK_DOOR_POWER,      _R( 620,    70, 648,  148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
		oapiRegisterPanelArea (AID_OUTER_AIRLOCK_DOOR_POWER,      _R( 670,    70, 698,  148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);
        oapiRegisterPanelArea (AID_DOCK_RELEASE_POWER,            _R( 720,    70, 748,  148), PANEL_REDRAW_ALWAYS, PANEL_MOUSE_LBDOWN);

		
		
		
		
		
		
		campos = CAM_EVA;
		break;







}
	InitPanel (id);
	return hBmp != NULL;
}




// ======
// API callback interface
// ======

// --------------------------------------------------------------
// Module initialisation
// --------------------------------------------------------------
DLLCLBK void InitModule (HINSTANCE hModule)
{
	g_Param.hDLL = hModule;
	oapiRegisterCustomControls (hModule);

	// allocate GDI resources
	g_Param.font[0]  = CreateFont (-13, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 0, "Arial");
	g_Param.font[1]  = CreateFont (-10, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Arial");
	g_Param.font[2]  = CreateFont (-10, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, "Arial");
	g_Param.font[3]  = CreateFont ( -7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, "Arial");
	g_Param.brush[0] = CreateSolidBrush (RGB(0,255,0));    // green
	g_Param.brush[1] = CreateSolidBrush (RGB(255,0,0));    // red
	g_Param.brush[2] = CreateSolidBrush (RGB(80,80,224));  // blue
	g_Param.brush[3] = CreateSolidBrush (RGB(160,120,64)); // brown
	g_Param.pen[0] = CreatePen (PS_SOLID, 1, RGB(224,224,224));
	g_Param.pen[1] = CreatePen (PS_SOLID, 3, RGB(164,164,164));
}

// --------------------------------------------------------------
// Module cleanup
// --------------------------------------------------------------
DLLCLBK void ExitModule (HINSTANCE hModule)
{
	oapiUnregisterCustomControls (hModule);

	int i;
	// deallocate GDI resources
	for (i = 0; i < 2; i++) DeleteObject (g_Param.font[i]);
	for (i = 0; i < 4; i++) DeleteObject (g_Param.brush[i]);
	for (i = 0; i < 2; i++) DeleteObject (g_Param.pen[i]);
}

// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
	// need to init device-dependent resources here in case the screen mode has changed
	g_Param.col[2] = oapiGetColour(80,80,224);
	g_Param.col[3] = oapiGetColour(160,120,64);

	return new DeltaGlider (hvessel, flightmodel);
}

// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
	if (vessel) delete (DeltaGlider*)vessel;
}


// ======
// Scenario editor interface
// ======

DeltaGlider *GetDG (HWND hDlg)
{
	// retrieve DG interface from scenario editor
	OBJHANDLE hVessel;
	SendMessage (hDlg, WM_SCNEDITOR, SE_GETVESSEL, (LPARAM)&hVessel);
	return (DeltaGlider*)oapiGetVesselInterface (hVessel);
}

void UpdateDamage (HWND hTab, DeltaGlider *dg)
{
	int i;
	char cbuf[256];

	i = (int)(dg->lwingstatus*100.0+0.5);
	sprintf (cbuf, "%d %%", i);
	SetWindowText (GetDlgItem (hTab, IDC_LEFTWING_STATUS), cbuf);
	oapiSetGaugePos (GetDlgItem (hTab, IDC_LEFTWING_SLIDER), i);
	i = (int)(dg->rwingstatus*100.0+0.5);
	sprintf (cbuf, "%d %%", i);
	SetWindowText (GetDlgItem (hTab, IDC_RIGHTWING_STATUS), cbuf);
	oapiSetGaugePos (GetDlgItem (hTab, IDC_RIGHTWING_SLIDER), i);
}

// --------------------------------------------------------------
// Message procedure for editor page 1 (animation settings)
// --------------------------------------------------------------
BOOL CALLBACK EdPg1Proc (HWND hTab, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
	case WM_COMMAND:
		switch (LOWORD (wParam)) {
		case IDHELP:
			g_hc.topic = "/SE_Anim.htm";
			oapiOpenHelp (&g_hc);
			return TRUE;
		case IDC_GEAR_UP:
			GetDG(hTab)->ActivateLandingGear (DeltaGlider::DOOR_CLOSED);
			return TRUE;
		case IDC_GEAR_DOWN:
			GetDG(hTab)->ActivateLandingGear (DeltaGlider::DOOR_OPEN);
			return TRUE;
		case IDC_OLOCK_CLOSE:
			GetDG(hTab)->ActivateOuterAirlock (DeltaGlider::DOOR_CLOSED);
			return TRUE;
		case IDC_OLOCK_OPEN:
			GetDG(hTab)->ActivateOuterAirlock (DeltaGlider::DOOR_OPEN);
			return TRUE;
		case IDC_ILOCK_CLOSE:
			GetDG(hTab)->ActivateInnerAirlock (DeltaGlider::DOOR_CLOSED);
			return TRUE;
		case IDC_ILOCK_OPEN:
			GetDG(hTab)->ActivateInnerAirlock (DeltaGlider::DOOR_OPEN);
			return TRUE;
		case IDC_NCONE_CLOSE:
			GetDG(hTab)->ActivateNoseCone (DeltaGlider::DOOR_CLOSED);
			return TRUE;
		case IDC_NCONE_OPEN:
			GetDG(hTab)->ActivateNoseCone (DeltaGlider::DOOR_OPEN);
			return TRUE;
		case IDC_LADDER_RETRACT:
			GetDG(hTab)->ActivateLadder (DeltaGlider::DOOR_CLOSED);
			return TRUE;
		case IDC_LADDER_EXTEND:
			GetDG(hTab)->ActivateLadder (DeltaGlider::DOOR_OPEN);
			return TRUE;
		case IDC_HATCH_CLOSE:
			GetDG(hTab)->ActivateHatch (DeltaGlider::DOOR_CLOSED);
			return TRUE;
		case IDC_HATCH_OPEN:
			GetDG(hTab)->ActivateHatch (DeltaGlider::DOOR_OPEN);
			return TRUE;
		case IDC_RADIATOR_RETRACT:
			GetDG(hTab)->ActivateRadiator (DeltaGlider::DOOR_CLOSED);
			return TRUE;
		case IDC_RADIATOR_EXTEND:
			GetDG(hTab)->ActivateRadiator (DeltaGlider::DOOR_OPEN);
			return TRUE;
		}
		break;
	}
	return FALSE;
}

// --------------------------------------------------------------
// Message procedure for editor page 2 (passengers)
// --------------------------------------------------------------
BOOL CALLBACK EdPg2Proc (HWND hTab, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	DeltaGlider *dg;
	int i;

	switch (uMsg) {
	case WM_INITDIALOG: {
		char cbuf[256];
		dg = (DeltaGlider*)oapiGetVesselInterface ((OBJHANDLE)lParam);
		for (i = 0; i < 4; i++)
			SendDlgItemMessage (hTab, IDC_CHECK1+i, BM_SETCHECK, dg->psngr[i] ? BST_CHECKED : BST_UNCHECKED, 0);
		sprintf (cbuf, "%0.2f kg", dg->GetMass());
		SetWindowText (GetDlgItem (hTab, IDC_MASS), cbuf);
		} break;
	case WM_COMMAND:
		switch (LOWORD (wParam)) {
		case IDC_CHECK1:
		case IDC_CHECK2:
		case IDC_CHECK3:
		case IDC_CHECK4: {
			char cbuf[256];
			i = SendDlgItemMessage (hTab, LOWORD(wParam), BM_GETCHECK, 0, 0);
			dg = GetDG(hTab);
			dg->psngr[LOWORD(wParam)-IDC_CHECK1] = (i ? true:false);
			dg->SetPassengerVisuals();
			dg->SetEmptyMass();
			sprintf (cbuf, "%0.2f kg", dg->GetMass());
			SetWindowText (GetDlgItem (hTab, IDC_MASS), cbuf);
			} break;
		}
		break;
	}
	return FALSE;
}

// --------------------------------------------------------------
// Message procedure for editor page 3 (damage)
// --------------------------------------------------------------
BOOL CALLBACK EdPg3Proc (HWND hTab, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	DeltaGlider *dg;

	switch (uMsg) {
	case WM_INITDIALOG: {
		dg = (DeltaGlider*)oapiGetVesselInterface ((OBJHANDLE)lParam);
		GAUGEPARAM gp = { 0, 100, GAUGEPARAM::LEFT, GAUGEPARAM::BLACK };
		oapiSetGaugeParams (GetDlgItem (hTab, IDC_LEFTWING_SLIDER), &gp);
		oapiSetGaugeParams (GetDlgItem (hTab, IDC_RIGHTWING_SLIDER), &gp);
		UpdateDamage (hTab, dg);
		} break;
	case WM_COMMAND:
		switch (LOWORD (wParam)) {
		case IDC_REPAIR:
			dg = GetDG(hTab);
			dg->RepairDamage ();
			UpdateDamage (hTab, dg);
			return TRUE;
		}
		break;
	case WM_HSCROLL:
		dg = GetDG(hTab);
		int id = GetDlgCtrlID ((HWND)lParam);
		switch (id) {
		case IDC_LEFTWING_SLIDER:
		case IDC_RIGHTWING_SLIDER:
			switch (LOWORD (wParam)) {
			case SB_THUMBTRACK:
			case SB_LINELEFT:
			case SB_LINERIGHT:
				if (id == IDC_LEFTWING_SLIDER)
					dg->lwingstatus = HIWORD(wParam)*0.01;
				else
					dg->rwingstatus = HIWORD(wParam)*0.01;
				dg->ApplyDamage ();
				UpdateDamage (hTab, dg);
				return TRUE;
			}
			break;
		}
		break;
	}
	return FALSE;
}

// --------------------------------------------------------------
// Add vessel-specific pages into scenario editor
// --------------------------------------------------------------
DLLCLBK void secInit (HWND hEditor, OBJHANDLE hVessel)
{
	DeltaGlider *dg = (DeltaGlider*)oapiGetVesselInterface (hVessel);

	EditorPageSpec eps1 = {"Animations", g_Param.hDLL, IDD_EDITOR_PG1, EdPg1Proc};
	SendMessage (hEditor, WM_SCNEDITOR, SE_ADDPAGEBUTTON, (LPARAM)&eps1);
	EditorPageSpec eps2 = {"Passengers", g_Param.hDLL, IDD_EDITOR_PG2, EdPg2Proc};
	SendMessage (hEditor, WM_SCNEDITOR, SE_ADDPAGEBUTTON, (LPARAM)&eps2);
	if (dg->bDamageEnabled) {
		EditorPageSpec eps3 = {"Damage", g_Param.hDLL, IDD_EDITOR_PG3, EdPg3Proc};
		SendMessage (hEditor, WM_SCNEDITOR, SE_ADDPAGEBUTTON, (LPARAM)&eps3);
	}
}

// ======
// Message callback function for control dialog box
// ======

BOOL CALLBACK Ctrl_DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	DeltaGlider *dg = (uMsg == WM_INITDIALOG ? (DeltaGlider*)lParam : (DeltaGlider*)oapiGetDialogContext (hWnd));
	// pointer to vessel instance was passed as dialog context

	switch (uMsg) {
	case WM_INITDIALOG:
		UpdateCtrlDialog (dg, hWnd);
		return FALSE;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDCANCEL:
			oapiCloseDialog (hWnd);
			return TRUE;
		case IDC_GEAR_UP:
			dg->ActivateLandingGear (DeltaGlider::DOOR_CLOSING);
			return 0;
		case IDC_GEAR_DOWN:
			dg->ActivateLandingGear (DeltaGlider::DOOR_OPENING);
			return 0;
		case IDC_NCONE_CLOSE:
			dg->ActivateNoseCone (DeltaGlider::DOOR_CLOSING);
			return 0;
		case IDC_NCONE_OPEN:
			dg->ActivateNoseCone (DeltaGlider::DOOR_OPENING);
			return 0;
		case IDC_OLOCK_CLOSE:
			dg->ActivateOuterAirlock (DeltaGlider::DOOR_CLOSING);
			return 0;
		case IDC_OLOCK_OPEN:
			dg->ActivateOuterAirlock (DeltaGlider::DOOR_OPENING);
			return 0;
		case IDC_ILOCK_CLOSE:
			dg->ActivateInnerAirlock (DeltaGlider::DOOR_CLOSING);
			return 0;
		case IDC_ILOCK_OPEN:
			dg->ActivateInnerAirlock (DeltaGlider::DOOR_OPENING);
			return 0;
		case IDC_LADDER_RETRACT:
			dg->ActivateLadder (DeltaGlider::DOOR_CLOSING);
			return 0;
		case IDC_LADDER_EXTEND:
			dg->ActivateLadder (DeltaGlider::DOOR_OPENING);
			return 0;
		case IDC_HATCH_CLOSE:
			dg->ActivateHatch (DeltaGlider::DOOR_CLOSING);
			return 0;
		case IDC_HATCH_OPEN:
			dg->ActivateHatch (DeltaGlider::DOOR_OPENING);
			return 0;
		case IDC_RADIATOR_RETRACT:
			dg->ActivateRadiator (DeltaGlider::DOOR_CLOSING);
			return 0;
		case IDC_RADIATOR_EXTEND:
			dg->ActivateRadiator (DeltaGlider::DOOR_OPENING);
			return 0;
		case IDC_NAVLIGHT:
			dg->SetNavlight (SendDlgItemMessage (hWnd, IDC_NAVLIGHT, BM_GETCHECK, 0, 0) == BST_CHECKED);
			return 0;
		case IDC_BEACONLIGHT:
			dg->SetBeacon (SendDlgItemMessage (hWnd, IDC_BEACONLIGHT, BM_GETCHECK, 0, 0) == BST_CHECKED);
			return 0;
		case IDC_STROBELIGHT:
			dg->SetStrobe (SendDlgItemMessage (hWnd, IDC_STROBELIGHT, BM_GETCHECK, 0, 0) == BST_CHECKED);
			return 0;
		//case IDC_DAMAGE:
		//	oapiOpenDialog (g_Param.hDLL, IDD_DAMAGE, Damage_DlgProc, dg);

		}
		break;
	}
	return oapiDefDialogProc (hWnd, uMsg, wParam, lParam);
}

void UpdateCtrlDialog (DeltaGlider *dg, HWND hWnd)
{
	static int bstatus[2] = {BST_UNCHECKED, BST_CHECKED};

	if (!hWnd) hWnd = oapiFindDialog (g_Param.hDLL, IDD_CTRL);
	if (!hWnd) return;

	int op;

	op = dg->gear_status & 1;
	SendDlgItemMessage (hWnd, IDC_GEAR_DOWN, BM_SETCHECK, bstatus[op], 0);
	SendDlgItemMessage (hWnd, IDC_GEAR_UP, BM_SETCHECK, bstatus[1-op], 0);

	op = dg->rcover_status & 1;
	SendDlgItemMessage (hWnd, IDC_RETRO_OPEN, BM_SETCHECK, bstatus[op], 0);
	SendDlgItemMessage (hWnd, IDC_RETRO_CLOSE, BM_SETCHECK, bstatus[1-op], 0);

	op = dg->NOSE_CONE_STATUS & 1;
	SendDlgItemMessage (hWnd, IDC_NCONE_OPEN, BM_SETCHECK, bstatus[op], 0);
	SendDlgItemMessage (hWnd, IDC_NCONE_CLOSE, BM_SETCHECK, bstatus[1-op], 0);

	op = dg->OUTER_AIRLOCK_DOOR_STATUS & 1;
	SendDlgItemMessage (hWnd, IDC_OLOCK_OPEN, BM_SETCHECK, bstatus[op], 0);
	SendDlgItemMessage (hWnd, IDC_OLOCK_CLOSE, BM_SETCHECK, bstatus[1-op], 0);

	op = dg->INNER_AIRLOCK_DOOR_STATUS & 1;
	SendDlgItemMessage (hWnd, IDC_ILOCK_OPEN, BM_SETCHECK, bstatus[op], 0);
	SendDlgItemMessage (hWnd, IDC_ILOCK_CLOSE, BM_SETCHECK, bstatus[1-op], 0);

	op = dg->ladder_status & 1;
	SendDlgItemMessage (hWnd, IDC_LADDER_EXTEND, BM_SETCHECK, bstatus[op], 0);
	SendDlgItemMessage (hWnd, IDC_LADDER_RETRACT, BM_SETCHECK, bstatus[1-op], 0);

	op = dg->hatch_status & 1;
	SendDlgItemMessage (hWnd, IDC_HATCH_OPEN, BM_SETCHECK, bstatus[op], 0);
	SendDlgItemMessage (hWnd, IDC_HATCH_CLOSE, BM_SETCHECK, bstatus[1-op], 0);

	op = dg->radiator_status & 1;
	SendDlgItemMessage (hWnd, IDC_RADIATOR_EXTEND, BM_SETCHECK, bstatus[op], 0);
	SendDlgItemMessage (hWnd, IDC_RADIATOR_RETRACT, BM_SETCHECK, bstatus[1-op], 0);

	op = dg->beacon[0].active ? 1:0;
	SendDlgItemMessage (hWnd, IDC_NAVLIGHT, BM_SETCHECK, bstatus[op], 0);
	op = dg->beacon[3].active ? 1:0;
	SendDlgItemMessage (hWnd, IDC_BEACONLIGHT, BM_SETCHECK, bstatus[op], 0);
	op = dg->beacon[5].active ? 1:0;
	SendDlgItemMessage (hWnd, IDC_STROBELIGHT, BM_SETCHECK, bstatus[op], 0);
}

//======
//                BJ's functions //update
//======
double DeltaGlider::get_angle_between_in_radians(long double ax, long double ay, long double az, long double bx, long double by, long double bz)
{
double pi = 3.14159265358979323846;
double dotproduct, lengtha, lengthb, result;

   dotproduct = (ax * bx) + (ay * by) + (az * bz);
   lengtha = sqrt(ax * ax + ay * ay + az * az);
   lengthb = sqrt(bx * bx + by * by + bz * bz);

   result = acos( dotproduct / (lengtha * lengthb) );

   if(dotproduct < 0)
   {
      if(result > 0)
         result += pi;
      else
         result -= pi;
   }
   return result;
}

void DeltaGlider::behindPlanet(void)
{
	
	OHplanet = GetGravityRef();
	OBJHANDLE vessOH = GetHandle ();
	
	oapiGetGlobalPos (OHplanet, &pos);
	oapiGetGlobalPos (vessOH, &pos2);
	
	sunPos = (_V(0,0,0));
	SunToPlanet_vector = sunPos - pos;
	PlanetToVessel_vector = pos - pos2;
	
	distancePlanetToSun = sqrt(  (SunToPlanet_vector.x*SunToPlanet_vector.x) + (SunToPlanet_vector.y*SunToPlanet_vector.y)+(SunToPlanet_vector.z*SunToPlanet_vector.z)   );
	
	double latitude;
	double longitude;
	hVessel = GetHandle();
OBJHANDLE BBB  = GetEquPos (
longitude,
latitude,rad);//OHplanet
		
	distancePlanetToVessel = ((GetAltitude()+ rad) );//
//	check = 0;
double x;
    
    y = get_angle_between_in_radians(SunToPlanet_vector.x,SunToPlanet_vector.y,SunToPlanet_vector.z,PlanetToVessel_vector.x,PlanetToVessel_vector.y,PlanetToVessel_vector.z);
    
    if (y == 0)   {y = 99999999999; }
    y = atan(y);
	x =  y * (57.29577951);
     
	rad -= GetAltitude();
    
    if (x > 90) { is_behind = 0;  return; }//infront of planet
 y= asin(y);
   DistPtoL = abs((y * distancePlanetToVessel));
   is_behind = 0;
   if (DistPtoL < (rad))
   		is_behind = 1;
   		
	
} //else { check++; }




void DeltaGlider::clbkSetClassCaps_UMMu(void)
{
	//--------------------------------------------------------------
	// InitUmmu
	// initialisation of Ummu must be done first ! return of 1 mean OK 
	// return of -999 mean Ummu addon is not installed in user's Orbiter, return of -1 
	// mean misc error. If error simply all function will fail silently 
	// and there will be no MMu. It's a good idea to warn the user. (see bottom of listing "clbkVisualCreated")
	UmmuSdKInitReturnCode=Crew.InitUmmu(GetHandle());	
	//--------------------------------------------------------------

	//--------------------------------------------------------------
	// GetUserUMmuVersion
	// this check wich version of UMmu addon the user have in his orbiter directory.
	// this may be usefull for future version with more function so you can check
	// if user installation support the new functions. Return -1 on error (not installed, version cannot be read)
	// or version number in float value (ie: 1.5="1.5" version etc etc)
	float UMmuVersion=Crew.GetUserUMmuVersion();

	//--------------------------------------------------------------
	// DefineAirLockShape
	// We set the airlock shape and state, this virtual box will be the one
	// into were a Ummu asking to reenter will be taken in account
	// first parameter is airlock door state (OPEN=TRUE) and other are X,X1,Y,Y1 and Z,Z1 
	// min and max coordinate for this virtual box (vessel local coordinate)
	// Pay attention to reenter when landed (if suitable) and make the box large enough so 
	// it's not a pain for the user to find airlock's entry.
	Crew.DefineAirLockShape(TRUE,-1,1,  -3,1,  14,17);			// Airlock open, 2 meter wide 4 meter high 6 meter long (vessel local coordinate)
    //Crew.DefineAirLockShape(TRUE,-1,1,-1,3,-2,4);

	//--------------------------------------------------------------
	// SetMembersPositionOrientationOnEVA
	// We define here were the Ummu will appear when they make an EVA
	// first parameter is position second is orientation, take care not to make
	// them appear to high on ground (will fall and die) or to low (Orbiter "light speed" bug)
	Crew.SetMembersPosRotOnEVA(_V(0,-2,15),_V(0,0,0));	// 3 meters in front of ship (z) facing direction of ship (vessel local coordinate)
    //Crew.SetMembersPosRotOnEVA(_V(0,0,3),_V(0,0,0));
	//---------------------------------------------------------------
	// finally set the maximum seat available in this ship, default is
	// 8 but it can go from 1 to 100
	// BAD IDEA: using this to "close" your ship, use "SetAirlockDoorState" instead.
	Crew.SetMaxSeatAvailableInShip(8);

	//------------------------------------------------------------------
	// IMPORTANT
	// at this point Ummu is ready to be used (appart save/load see below "clbkSaveState" "clbkLoadStateEx")
	// we'll add below some >default< crew member for when the ship is spawned by Orbiter's 
	// scenerio editor. (As there is no "scn" scenario loading in this case, your ship would have no crew)
	// pay attention that if a scenario is loaded the members added here will be deleted first. 
	// You can also add new members at any time during runtime.
	// IDEA: Make here a selection of random name, crew, number age, etc etc. Up to you,
	// each scenario created dynamically would have then a different crew.
	//------------------------------------------------------------------

	//--------------------------------------------------------------
	// AddCrewMember
	// We'll add four members, parameters are name, age, cardiac pulse,weight (in kilogramm)
	// notice a fourth optional parameter exist wich allow you to set misc data of
	// max four characters, usefull if you want to distinguish your members for any purpose
	// (eg: "Capt"=captain "Eng" =engineer "UK" nationality etc etc) 
	// You can add up to 100 crew members in your ship, take care your Vessel's empty mass will be updated 
	// automatically with crew's weight (you can disable this feature see header)
	// Return 1 on success -1 on error (probably vessel full, name>25 char 
	// age, pulse or weight out of realistic range or MiscID>4 char)
	// IDEA: Use the MiscID parameter to EVA with different spacesuit (captain,girl,english people etc etc)
	/*Crew.AddCrewMember("Russ Hicks",41,65,74,"Capt");		//(for name and id a-z A-Z 0-9 characters only)
	Crew.AddCrewMember("Chuck Hicks",27,67,55,"Eng");	//(for name and id a-z A-Z 0-9 characters only)
	Crew.AddCrewMember("Dave Mezera",15,70,45,"Doc");	//(for name and id a-z A-Z 0-9 characters only)
	Crew.AddCrewMember("Albert Jr Falcon",15,70,45);		//(for name and id a-z A-Z 0-9 characters only)
	Crew.AddCrewMember("Peter Falcon",15,70,45); //Peter Falcon
    Crew.AddCrewMember("Sam Waterson",15,70,45);
    Crew.AddCrewMember("Dan Goodman",15,70,45);
	Crew.AddCrewMember("Jim Jones",15,70,45);
*/

	// this variables below are used by the simple user text interface used in this demo
	// see function "SendFocusScreenMessage" below for explaination.
	strcpy(cOurMessage,"");
}





//------------------------------------------------------------------------------------------------------------------
// UTILITY FONCTION  -  UTILITY FONCTION  - UTILITY FONCTION  - UTILITY FONCTION  - UTILITY FONCTION
//
// This below is not mandatory for UMmu to run, anyway such functions can help you to implement UMmu
// in your addon. A recommended read at least.
//
//------------------------------------------------------------------------------------------------------------------



///////////////////////////////////////////////////////////////////////////////////////////
//
// USING STANDARD FUNCTION ID,NAME AND SPACESUIT (Good idea)
//
// The deltagliderIV and maybe other ship understand MiscID parameter as a way to determine
// function aboard and the spacesuit to use when EVA (7 colors differents). For example only
// crew with MiscID="Capt" are able to take command in ship and they wear a orange spacesuit
// with "Capt" logo on helmet. You can find which MiscID correspond to which function or spacesuit
// mesh by looking declaration at top of UMmuSDK.h variables: UmmuMiscID[] UmmuFunctionName[]
// and UmmuMeshUsed[]. You can find below a function that demonstrate how to EVA one crew member
// using the proper standard mesh in regards of his MiscID. This function can be used instead
// of UMmu function "EvaCrewMember" it work exactly the same way.
//
// Function: EvaCrewMemberWithStandardSpacesuit(char* CrewName)
// Purpose: EVA one member of your ship with standard spacesuit in regard of his MiscID.
// CrewName: The name of one crew member. (eg: "John Doe")
// Return: The same return code than UMmu "EvaCrewMember()" function.
//
// TEST: replace "Crew.EvaCrewMember" in code above with this function and launch
//       the scenario "UMmu SDK demo EVA" they will EVA with different spacesuit
//
///////////////////////////////////////////////////////////////////////////////////////////
int DeltaGlider::EvaCrewMemberWithStandardSpacesuit(char* CrewName)
{
	char TempMiscID[5]={0};
	int I=0;
	char MeshToUse[26]={"ummu/ummu"}; // default mesh if not found
	// retriew the crew's MiscID
	strcpy(TempMiscID,Crew.GetCrewMiscIdByName(CrewName));
	// search if we find this ID in the list
	for(I=0;I<NUMBER_OF_MMU_TYPE;I++)
	{
		if(strcmp(UmmuMiscID[I],TempMiscID)==0)
		{
			// found ! copy the mesh filename to use for EVA
			strcpy(MeshToUse,UmmuMeshUsed[I]);
			break;
		}
	}
	// Set the mesh filename to use
	Crew.SetAlternateMeshToUseForEVASpacesuit(MeshToUse);
	// Eva the crew member with this mesh
	return Crew.EvaCrewMember(CrewName);
}


///////////////////////////////////////////////////////////////////////////////////////////
// USING TEXT INTERFACE FOR CREW MANAGMENT (not a good idea)
//
// This is customs function that send oapiDebugString() Message on screen
// it simply avoid that the message is sent if our ship don't have the focus
// and ensure that message will be reminded when we focus back on ship
// the Orbiter function below clbkFocusChanged is used to erase message when
// we lost focus.
// it's a bad idea to do an UMmu user interface only by using Debug screen message 
// but if you can't do better you may use this system.
// DON'T forget to initialise cOurMessage in clbksetclasscap or you
// may have Crash to Desktop.
///////////////////////////////////////////////////////////////////////////////////////////
char *DeltaGlider::SendFocusScreenMessage()
{
	return cOurMessage;
}
void DeltaGlider::clbkFocusChanged(bool getfocus,OBJHANDLE hNewVessel,OBJHANDLE hOldVessel)
{
	// erase message if we focus to another vessel
	if(!getfocus)
	{
		strcpy(oapiDebugString(),"");
	}
}

//void DeltaGlider::clbkPreStep (double simt, double simdt, double mjd)


// ======
// Message callback function for damage dialog box
// ======

#ifdef UNDEF
BOOL CALLBACK Damage_DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	DeltaGlider *dg = (uMsg == WM_INITDIALOG ? (DeltaGlider*)lParam : (DeltaGlider*)oapiGetDialogContext (hWnd));
	// pointer to vessel instance was passed as dialog context

	switch (uMsg) {
	case WM_INITDIALOG:
		return FALSE;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDCANCEL:
			oapiCloseDialog (hWnd);
			return TRUE;
		case IDC_REPAIR:
			dg->RepairDamage();
			return 0;
		}
		break;
	}
	return oapiDefDialogProc (hWnd, uMsg, wParam, lParam);
}

void UpdateDamageDialog (DeltaGlider *dg, HWND hWnd)
{
	if (!hWnd) hWnd = oapiFindDialog (g_Param.hDLL, IDD_DAMAGE);
	if (!hWnd) return;

	char cbuf[16];
	sprintf (cbuf, "%0.0f %%", dg->lwingstatus*100.0);
	SetWindowText (GetDlgItem (hWnd, IDC_LEFTWING_STATUS), cbuf);
	sprintf (cbuf, "%0.0f %%", dg->rwingstatus*100.0);
	SetWindowText (GetDlgItem (hWnd, IDC_RIGHTWING_STATUS), cbuf);
}
#endif
